Come eseguire il tempo su più comandi E scrivere il tempo di output su file?


66

Voglio eseguire il timecomando per misurare il tempo di diversi comandi.

Quello che voglio fare è:

  • Misura il tempo di esecuzione di tutti loro sommati
  • Scrivi l' timeoutput in un file
  • Scrivi il STDERRdal comando che sto misurandoSTDERR

Quello che NON voglio fare è

  • Scrivi i vari comandi in uno script separato (perché? Perché tutto questo è già uno script che sto generando in modo programmatico e creare UN ALTRO script temporaneo sarebbe più un disastro di quello che voglio)

Cosa ho provato finora:

/usr/bin/time --output=outtime -p echo "a"; echo "b";

Non funziona, timeviene eseguito solo sul primo.

/usr/bin/time --output=outtime -p ( echo "a"; echo "b"; )

Non funziona, (è un token inaspettato.

/usr/bin/time --output=outtime -p { echo "a"; echo "b"; }

Non funziona, "nessun file o directory".

/usr/bin/time --output=outtime -p ' echo "a"; echo "b";'

Non funziona, "nessun file o directory".

time ( echo "a"; echo "b"; ) 2>outtime

Non funziona, poiché reindirizza tutto STDERRin outtime; Voglio solo l' timeuscita di lì.

Ed ovviamente,

time --output=outime echo "a";

Non funziona, dal momento --output=outime: command not found.

Come posso farlo?

Risposte:


90

Utilizzare sh -c 'commands'il comando, per esempio:

/usr/bin/time --output=outtime -p sh -c 'echo "a"; echo "b"'

2
una versione più breve:time -p sh -c 'echo "a"; echo "b"'
Geo

8

Prova questo:

% (time ( { echas z; echo 2 } 2>&3 ) ) 3>&2 2>timeoutput
zsh: command not found: echas
2
% cat timeoutput                                
( { echas z; echo 2; } 2>&3; )  0.00s user 0.00s system 0% cpu 0.004 total

Spiegazione:

Innanzitutto, dobbiamo trovare un modo per reindirizzare l'output di time. Poiché timeè un comando shell, prende la linea di comando completa come comando da misurare, compreso reindirizzamenti. Così,

% time whatever 2>timeoutput
whatever 2> timeoutput  0.00s user 0.00s system 0% cpu 0.018 total
% cat timeoutput 
zsh: command not found: whatever

[Nota: il commento di janos implica che non è questo il caso bash.] Possiamo ottenere il reindirizzamento timedell'output eseguendo timeuna subshell e quindi reindirizzando l'output di quella subshell.

% (time whatever) 2> timeoutput
% cat timeoutput 
zsh: command not found: whatever
whatever  0.00s user 0.00s system 0% cpu 0.018 total

Ora abbiamo reindirizzato con successo l'output di time, ma il suo output è mescolato con l'output di errore del comando che stiamo misurando. Per separare i due, utilizziamo un descrittore di file aggiuntivo.

All'esterno abbiamo

% (time ... ) 3>&2 2>timeout

Ciò significa: qualunque cosa sia scritta nel descrittore di file 3, verrà emessa nello stesso posto che il descrittore di file 2 (errore standard) sta emettendo ora (il terminale). E quindi reindirizziamo l'errore standard al file timeout.

Quindi ora abbiamo: tutto ciò che è stato scritto su stdout e fd 3 andrà al terminale e tutto ciò che è stato scritto su stderr andrà al file. Ciò che resta è reindirizzare lo stderr del comando misurato su fd 3.

% (time whatever 2>&3) 3>&2 2>timeout

Ora, per fare in modo che il tempo misuri più di un comando, dobbiamo eseguirli in una (altra!) Subshell (tra parentesi). E per reindirizzare l'output di errore di tutti loro su fd 3, dobbiamo raggrupparli tra parentesi graffe.

Quindi, finalmente, arriviamo a:

% (time ( { whatever; ls } 2>&3 ) ) 3>&2 2>timeoutput

Questo è tutto.


Questo è un errore di sintassi in una shell POSIX. Probabilmente un bashismo?
Jos

@josch la shell usata qui è zsh.
angus,

6

Non è la risposta corretta ma molto correlata alla domanda.
Ottieni statistiche temporali per più programmi tra parentesi sono obbligatori. Separare i comandi con punto e virgola.

time ( command1 ; command2 )

1
Questo è carino. Meglio ancora, usa && tra i comandi, in modo time ( command1 && command2 )tale che se il primo comando fallisce; non procederà all'esecuzione dell'altro.
bikashg
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.