Reindirizzare l'output di un comando in `time command`


11

Sto cercando di cronometrare qualcosa usando:

/usr/bin/time myCommand

Tuttavia, poiché /usr/bin/timescrive su stderr, se anche myCommand scrive su stderr, otterrò più di un semplice output di tempo sullo stream. Quello che voglio fare è reindirizzare tutto l'output di myCommand /dev/null, ma comunque scrivere l'output del tempo su stderr. Usando un esempio di myCommand che scrive su stderr di ls /nofile, vediamo che (ovviamente) non c'è alcun output con il seguente:

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

Senza alcun reindirizzamento, vediamo sia l'output da ls(a stderr) che l'output dal tempo (anche a 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

Quello che voglio è qualcosa che semplicemente produce:

$ /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

Qualche idea?


Sto usando il comando time nel file di script. voglio l'output di tempo in stdout anziché in stderr. come posso ottenere questo?

Risposte:


20

In ksh, bash e zsh, timeè una parola chiave, non un builtin. I reindirizzamenti sulla stessa riga si applicano solo al comando a tempo, non all'output di timese stesso.

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

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

Per reindirizzare l'output da timese stesso in queste shell, è necessario utilizzare un livello aggiuntivo di raggruppamento.

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

Se si utilizza la versione GNU timedell'utilità standalone , ha -oun'opzione per scrivere l'output di timealtrove rispetto a stderr. Puoi timescrivere sul terminale:

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

Se si desidera mantenere l'output timesul suo errore standard, è necessario un livello aggiuntivo di shuffle per la descrizione dei file.

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

Con qualsiasi timeutilità, è possibile richiamare una shell intermedia per eseguire i reindirizzamenti desiderati. Invocare una shell intermedia per eseguire azioni extra come cdreindirizzamenti, ecc. È abbastanza comune: è il tipo di piccole cose che le shell sono progettate per fare.

/usr/bin/time sh -c 'exec mycommand >/dev/null 2>/dev/null'

Un paio di follow-up: 1) Cosa fa "exec" nel tuo ultimo suggerimento? Sembra funzionare senza di essa: / usr / bin / time sh -c 'exec ls / nofile &> ./ output.dat' 2) È una "shell intermedia" uguale a una "subshell" (che otterresti io pensi di usare le parentesi?). Avevo provato cose come / usr / bin / time (ls / nofile &> ./ output.dat) senza alcun risultato. 3) Che cos'è / dev / tty? So che tty0 è stdin, tty1 = stdout, tty2 = stderr, ma per quanto riguarda solo 'tty'?
David Doria,

4) Con l'opzione / dev / fd3, sembra che tu stia dicendo di scrivere l'output -o su 3, quindi reindirizzare 3 su 2, 1 su null e 2 su null. Questo non dovrebbe inviare 3 a null anche dal momento che i reindirizzamenti avvengono da sinistra a destra?
David Doria,

1
@DavidDoria execsostituisce la shell con il programma specificato invece di eseguirlo come sottoprocesso. Alcune shell eseguono questa ottimizzazione automaticamente quando un comando è l'ultimo in uno script. "Shell intermedia" significa proprio questo: una shell che è tra timee mycommand; non è correlato ai subshells. /dev/ttyè il terminale su cui è in esecuzione il comando (non è collegato a /dev/ttyNUMquali sono le console fisiche; stai confondendo con i descrittori di file: stdin è /dev/fd/0, ecc.).
Gilles 'SO- smetti di essere cattivo' il

@DavidDoria La modifica di ciò a cui è collegato un descrittore di file avviene da sinistra a destra, il che ha l'effetto opposto. Vedi unix.stackexchange.com/questions/23964/… o unix.stackexchange.com/questions/37660/order-of-redirections
Gilles 'SO- smetti di essere malvagio'

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

Non è lo stesso "tempo" (credo sia un alias bash). Si noti che non segue alcuna regola di reindirizzamento ragionevole? $ time &> / dev / null real 0m0.000s user 0m0.000s sys 0m0.000s
David Doria

1
Che ne dici di questo: / usr / bin / time -o time / usr / bin / find / etc / pki / CA / private / &> / dev / null; cat time
Artur Szymczak,

Sì, l'ho visto, ma ero più curioso di sapere come farlo senza usare un meccanismo interno come -o.
David Doria,

@DavidDoria Cosa ti dà l'impressione che timesia un alias bash? which timeviene visualizzato /usr/bin/timein CentOS 5.7.
Timothy Martin,

type timeti mostrerà:time is a shell keyword
Artur Szymczak il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.