Come reindirizzare l'output del comando time su un file in Linux?


202

Solo una piccola domanda sui programmi di temporizzazione su Linux: il comando time consente di misurare il tempo di esecuzione di un programma:

[ed@lbox200 ~]$ time sleep 1

real    0m1.004s
user    0m0.000s
sys     0m0.004s

Che funziona benissimo. Ma se provo a reindirizzare l'output su un file, fallisce.

[ed@lbox200 ~]$ time sleep 1 > time.txt

real    0m1.004s
user    0m0.001s
sys     0m0.004s

[ed@lbox200 ~]$ cat time.txt 
[ed@lbox200 ~]$ 

So che ci sono altre implementazioni del tempo con l'opzione -o per scrivere un file, ma la mia domanda riguarda il comando senza quelle opzioni.

Eventuali suggerimenti ?


3
Possibile duplicato di script bash scrivere tempo di esecuzione in un file , e sono tutt'altro che convinto che questa sia la prima domanda del genere.
Jonathan Leffler,

Risposte:


266

Provare

{ time sleep 1 ; } 2> time.txt

che combina lo STDERR di "time" e il tuo comando in time.txt

Oppure usa

{ time sleep 1 2> sleep.stderr ; } 2> time.txt

che inserisce STDERR da "sleep" nel file "sleep.stderr" e solo STDERR da "time" va in "time.txt"


2
Grazie, questo risponde esattamente alla mia domanda. Se ho capito bene, il risultato del comando time può essere ottenuto da stderr?
ed82,

7
Sì, ma devi metterlo tra parentesi graffe, altrimenti il ​​reindirizzamento farà parte del comando che timevaluta.
Gennaio

5
@Daniel Potresti sempre reindirizzare l'output del comando interno separatamente (es. {Time sleep 1 2> sleepStdErr.txt;} 2> time.txt) e questo ti darebbe solo l'output del tempo. Non sono sicuro se c'è un modo per ottenerlo in modo indipendente altrimenti.
gms7777,

10
Se vuoi usare il tempo con qualcosa come grep che legge di stdout, prova { time sleep 1; } 2>&1 | grep real. Questo invia stderr a stdout che grep può quindi leggere.
clayzermk1,

9
NON dimenticare il ';' carattere prima di chiudere '}', NON funzionerà senza (l'ho fatto, e ... mi chiedo perché non
funzioni

38

Avvolgi timee il comando che stai calcolando in una serie di parentesi.

Ad esempio, i seguenti tempi lse scrive il risultato lse i risultati della temporizzazione in outfile:

$ (time ls) > outfile 2>&1

Oppure, se si desidera separare l'output del comando dall'output acquisito da time:

$ (time ls) > ls_results 2> time_results

12
Non è necessario introdurre una subshell qui.
Gennaio

1
@ sampson-chen Funziona solo perché ls non scrive nulla su stderr, giusto? Come "separeresti" l'output di "time" da quello del comando da eseguire se il comando scrive sia su stdout che su stderr?
David Doria,

36

Semplice. L' timeutilità GNU ha un'opzione per questo.

Ma devi assicurarti di non usare il timecomando incorporato della tua shell , almeno il bashbuiltin non fornisce questa opzione! Ecco perché è necessario fornire il percorso completo timedell'utilità:

/usr/bin/time -o time.txt sleep 1

È inoltre possibile utilizzare il non-built-in senza specificare il percorso completo: stackoverflow.com/questions/29540540/...
Ciro Santilli郝海东冠状病六四事件法轮功

14

Se ti preoccupi dell'output dell'errore del comando, puoi separarli in questo modo mentre usi ancora il comando incorporato time.

{ time your_command 2> command.err ; } 2> time.log

o

{ time your_command 2>1 ; } 2> time.log

Come vedi gli errori del comando vai a un file (poiché stderrè usato per time).

Sfortunatamente non puoi inviarlo a un altro handle (come 3>&2) poiché non esisterà più al di fuori di{...}

Detto questo, se puoi usare il tempo GNU, fai solo quello che ha detto @Tim Ludwinski.

\time -o time.log command

8

Poiché l'output del comando 'time' è output dell'errore, reindirizzarlo come output standard sarebbe più intuitivo per eseguire ulteriori elaborazioni.

{ time sleep 1; } 2>&1 |  cat > time.txt

6

Se stai usando il tempo GNU invece del bash integrato, prova

time -o outfile command

(Nota: il tempo GNU viene formattato in modo leggermente diverso rispetto al bash incorporato).


1
Questo grazie. E puoi usare \time -o outfile command(con ``) per usare GNU invece che integrato.
Segna il

3
&>out time command >/dev/null

nel tuo caso

&>out time sleep 1 >/dev/null

poi

cat out

3
Un'idea elegante, ma porta alla shell che non usa il suo comando integrato. Se non hai timeinstallato un vero binario, outconterrà qualcosa di simile bash: time: command not found.
scy

Anche il formato per l'ora GNU non è lo stesso di quello incorporato in bash, causando problemi per l'analisi automatica.
Guss,

3

Ho finito per usare:

/usr/bin/time -ao output_file.txt -f "Operation took: %E" echo lol
  • Dove "a" è append
  • Dove "o" è seguito dal nome del file da aggiungere
  • Dove "f" è un formato con una sintassi simile a printf
  • Dove "% E" produce 0:00:00; ore: minuti: secondi
  • Ho dovuto invocare / usr / bin / time perché il "time" bash lo stava calpestando e non ha le stesse opzioni
  • Stavo solo cercando di ottenere l'output su file, non la stessa cosa di OP

2
#!/bin/bash

set -e

_onexit() {
    [[ $TMPD ]] && rm -rf "$TMPD"
}

TMPD="$(mktemp -d)"
trap _onexit EXIT

_time_2() {
    "$@" 2>&3
}

_time_1() {
    time _time_2 "$@"
}

_time() {
    declare time_label="$1"
    shift
    exec 3>&2
    _time_1 "$@" 2>"$TMPD/timing.$time_label"
    echo "time[$time_label]"
    cat "$TMPD/timing.$time_label"
}

_time a _do_something
_time b _do_another_thing
_time c _finish_up

Questo ha il vantaggio di non generare sub shell e la pipeline finale ha lo stderr ripristinato al vero stderr.


0

Se non si desidera toccare il processo originale 'stdout e stderr, è possibile reindirizzare stderr al descrittore di file 3 e ritorno:

$ { time { perl -le "print 'foo'; warn 'bar';" 2>&3; }; } 3>&2 2> time.out
foo
bar at -e line 1.
$ cat time.out

real    0m0.009s
user    0m0.004s
sys     0m0.000s

Puoi usarlo per un wrapper (ad esempio per cronjobs) per monitorare i tempi di esecuzione:

#!/bin/bash

echo "[$(date)]" "$@" >> /my/runtime.log

{ time { "$@" 2>&3; }; } 3>&2 2>> /my/runtime.log

0

Se stai usando cshpuoi usare:

/usr/bin/time --output=outfile -p $SHELL  -c 'your command'

Per esempio:

/usr/bin/time --output=outtime.txt -p csh -c 'cat file'
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.