Reindirizzare l'output del comando time in unix in una variabile in bash?


13

Voglio solo catturare l'output di un comando time cioè:

X=$(time ls)

o

$(time ls) | grep real

Tuttavia, la funzione time lo sputa sulla console. Come faccio a fare questo?

Risposte:


12

X = `(tempo ls) 2> & 1 | grep real`


Non hai bisogno di una subshell solo per time; La risposta di Dennis Williamson è migliore al riguardo.
musiphil

11

Vedi BashFAQ / 032 .

$ # captures output of command and time
$ time=$( TIMEFORMAT="%R"; { time ls; } 2>&1 )    # note the curly braces

$ # captures the time only, passes stdout through
$ exec 3>&1 4>&2
$ time=$(TIMEFORMAT="%R"; { time ls 1>&3 2>&4; } 2>&1)
bar baz
$ exec 3>&- 4>&-

Il tempo apparirà come "0.000" usando TIMEFORMAT="%R"quale sarà il tempo "reale".


potresti spiegarci un po 'come funziona? Ho usato uno snippet come questo stile cult di carico per anni. Cos'è lo stream 3 e 4? e il '-' ?
Sirex,

1
@Sirex: i flussi 3 e 4 sono flussi creati dal execcomando nella mia risposta utilizzando i descrittori di file disponibili. È possibile utilizzare qualsiasi descrittore di file disponibile. Gli stream 3 e 4 sono copie di 1 ( stdout) e 2 ( stderr), rispettivamente. Ciò consente all'output di lsdi passare normalmente a stdoute stderrtramite 3 e 4 mentre l'output di time(che normalmente passa a stderr) viene reindirizzato all'originale stdout(1) e quindi acquisito nella variabile mediante la sostituzione del comando. Come puoi vedere nel mio esempio, i nomi dei file bare bazvengono inviati al terminale. ...
In pausa fino a nuovo avviso.

1
... Una volta terminato, i flussi extra vengono chiusi usando il trailing -.
In pausa fino a ulteriore avviso.

4

Time scrive il proprio output su STDERR anziché su STDOUT. A peggiorare le cose, per impostazione predefinita 'time' è un comando incorporato della shell, quindi se si tenta di 'time ls 2> & 1' il '2> & 1' si applica solo a 'ls'.

La soluzione sarebbe probabilmente qualcosa del tipo:

/usr/bin/time -f 'real %e' -o OUTPUT_FILE ls > /dev/null 2>&1<br>
REALTIME=$(cat OUTPUT_FILE | cut -f 2 -d ' ')

Ci sono modi più fantasiosi per farlo, ma questo è il modo chiaro / semplice.


Sono interessato a farlo senza -o. Puoi pubblicare uno dei metodi fantasiosi a cui stavi pensando :)?
David Doria,

0

La risposta di @Dennis Williamson è ottima, ma non aiuta a memorizzare l'output del comando in una variabile e l'output di timein un'altra variabile. Questo in realtà non è possibile utilizzando i descrittori di file.

Se si desidera registrare il tempo necessario per l'esecuzione di un programma, è possibile farlo sottraendo l'ora di inizio dall'ora di fine. Ecco un semplice esempio che mostra quanti millisecondi un programma ha impiegato per essere eseguito:

START_TIME=$(date +%s%3N)
OUTPUT=$(ls -l)
ELAPSED_TIME=$(expr $(date +%s%3N) - $START_TIME)
echo "Command finished in $ELAPSED_TIME milliseconds"

Questo non è accurato come il timecomando, ma dovrebbe funzionare perfettamente per la maggior parte degli script bash.

Sfortunatamente il datecomando di Mac non supporta il %Nformato, ma puoi installare coreutils( brew install coreutils) e usare gdate:

START_TIME=$(gdate +%s%3N)
OUTPUT=$(ls -l)
ELAPSED_TIME=$(expr $(gdate +%s%3N) - $START_TIME)
echo "Command finished in $ELAPSED_TIME milliseconds"
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.