Redirect output dari sebuah perintah di `time command`

11

Saya mencoba menghitung waktu menggunakan:

/usr/bin/time myCommand

Namun, sejak /usr/bin/timemenulis ke stderr, jika myCommand juga menulis ke stderr, saya akan mendapatkan lebih dari sekadar keluaran waktu di arus. Yang ingin saya lakukan adalah, mengarahkan semua output myCommand ke /dev/null, tetapi masih menulis output waktu ke stderr. Menggunakan contoh myCommand yang menulis ke stderr ls /nofile, kita melihat bahwa (jelas) tidak ada output sama sekali dengan yang berikut ini:

$ /usr/bin/time ls /nofile 2> /dev/null
$

Tanpa pengalihan, kami melihat output dari ls(ke stderr) dan output dari waktu (juga ke stderr):

$ /usr/bin/time ls /nofile
ls: cannot access /nofile: No such file or directory
0.00user 0.00system 0:00.00elapsed 0%CPU (0avgtext+0avgdata 3776maxresident)k
0inputs+0outputs (0major+278minor)pagefaults 0swaps

Yang saya inginkan adalah sesuatu yang hanya menghasilkan:

$ /usr/bin/time ls /nofile > RedirectThatImAskingFor
0.00user 0.00system 0:00.00elapsed 0%CPU (0avgtext+0avgdata 3776maxresident)k
0inputs+0outputs (0major+278minor)pagefaults 0swaps

Ada ide?

David Doria
sumber
Saya menggunakan perintah waktu dalam file skrip. saya ingin output waktu di stdout daripada stderr. bagaimana saya bisa mendapatkan ini?
terkait: stackoverflow.com/questions/13356628/…
Ciro Santilli 冠状 病毒 审查 六四 六四 事件 法轮功

Jawaban:

20

Di ksh, bash dan zsh, timeadalah kata kunci, bukan builtin. Pengalihan pada baris yang sama hanya berlaku untuk perintah yang diatur waktunya, bukan ke output timeitu sendiri.

$ time ls -d / /nofile >/dev/null 2>/dev/null

real    0m0.003s
user    0m0.000s
sys     0m0.000s

Untuk mengarahkan output dari timedirinya sendiri di shell ini, Anda perlu menggunakan tingkat pengelompokan tambahan.

{ time mycommand 2>&3; } 3>&2 2>mycommand.time

Jika Anda menggunakan versi GNU dari timeutilitas mandiri , ia memiliki -oopsi untuk menulis output di timetempat lain daripada stderr. Anda dapat timemenulis ke terminal:

/usr/bin/time -o /dev/tty mycommand >/dev/null 2>/dev/null

Jika Anda ingin menjaga output dari timekesalahan standarnya, Anda memerlukan level tambahan file shuffling deskriptor.

/usr/bin/time -o /dev/fd/3 mycommand 3>&2 >/dev/null 2>/dev/null

Dengan timeutilitas apa pun , Anda dapat meminta shell perantara untuk melakukan pengalihan yang diinginkan. Meminta shell perantara untuk melakukan tindakan tambahan seperti cd, pengalihan, dll. Cukup umum - itu adalah jenis hal kecil yang dirancang untuk dilakukan oleh shell.

/usr/bin/time sh -c 'exec mycommand >/dev/null 2>/dev/null'
Gilles 'SANGAT berhenti menjadi jahat'
sumber
Beberapa tindak lanjut: 1) Apa yang dilakukan 'eksekutif' dalam saran terakhir Anda? Tampaknya berfungsi tanpa itu: / usr / bin / time sh -c 'exec ls / nofile &> ./ output.dat' 2) Adalah "shell menengah" yang sama dengan "subkulit" (yang akan Anda dapatkan berpikir menggunakan tanda kurung?). Saya telah mencoba hal-hal seperti / usr / bin / time (ls / nofile &> ./ output.dat) tetapi tidak berhasil. 3) Apa itu / dev / tty? Saya tahu tty0 adalah stdin, tty1 = stdout, tty2 = stderr, tapi bagaimana dengan 'tty' saja?
David Doria
4) Dengan opsi / dev / fd3, sepertinya Anda mengatakan untuk menulis -o output ke 3, kemudian mengarahkan 3 ke 2, 1 ke nol, dan 2 ke nol. Bukankah seharusnya itu mengirim 3 ke nol juga karena terjadi pengalihan dari kiri ke kanan?
David Doria
1
@ Davidvidoria execmengganti shell dengan program yang ditentukan alih-alih menjalankan program itu sebagai subproses. Beberapa shell melakukan optimasi ini secara otomatis ketika sebuah perintah adalah yang terakhir dalam sebuah skrip. "Shell perantara" berarti hanya itu: shell yang berada di antara timedan mycommand; itu tidak terkait dengan subkulit. /dev/ttyadalah terminal yang menjalankan perintah (itu tidak terkait dengan /dev/ttyNUMyang merupakan konsol fisik; Anda bingung dengan deskriptor file: stdin /dev/fd/0, dll).
Gilles 'SANGAT berhenti menjadi jahat'
@ Davidvidoria Mengubah apa descriptor file yang terhubung terjadi dari kiri ke kanan, yang memiliki efek sebaliknya. Lihat unix.stackexchange.com/questions/23964/… atau unix.stackexchange.com/questions/37660/order-of-redirections
Gilles 'SO-stop being evil'
0
[artur@asus-ux21e ~]$ find /etc/pki/CA/private/
/etc/pki/CA/private/
find: ‘/etc/pki/CA/private/’: Permission denied
[artur@asus-ux21e ~]$ time (find /etc/pki/CA/private/ &> /dev/null)

real    0m0.006s
user    0m0.001s
sys 0m0.004s
Artur Szymczak
sumber
Itu bukan 'waktu' yang sama (ini adalah bash alias saya percaya). Perhatikan bahwa itu tidak mengikuti aturan redirection yang masuk akal? $ time &> / dev / null real 0m0,000 pengguna 0m0,000s sys 0m0,000s
David Doria
1
Bagaimana dengan ini: / usr / bin / waktu -o waktu / usr / bin / find / etc / pki / CA / private / &> / dev / null; waktu kucing
Artur Szymczak
Ya saya pernah melihat itu, tapi saya lebih penasaran tentang bagaimana melakukannya tanpa menggunakan mekanisme internal seperti -o.
David Doria
@DavidDoria Apa yang memberi Anda kesan timealias bash? which timeditampilkan /usr/bin/timedalam CentOS 5.7.
Timothy Martin
type timeakan menunjukkan kepada Anda:time is a shell keyword
Artur Szymczak