¿Cómo redirigir la salida del comando de tiempo a un archivo en Linux?


202

Solo una pequeña pregunta sobre los programas de temporización en Linux: el comando time permite medir el tiempo de ejecución de un programa:

[ed@lbox200 ~]$ time sleep 1

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

Que funciona bien. Pero si trato de redirigir la salida a un archivo, falla.

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

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

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

Sé que hay otras implementaciones de tiempo con la opción -o para escribir un archivo, pero mi pregunta es sobre el comando sin esas opciones.

Alguna sugerencia ?


3
Posible duplicado del tiempo de ejecución de escritura de script bash en un archivo , y estoy lejos de estar convencido de que esta es la primera pregunta.
Jonathan Leffler

Respuestas:


266

Tratar

{ time sleep 1 ; } 2> time.txt

que combina el STDERR de "tiempo" y su comando en time.txt

O usar

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

que pone STDERR de "sleep" en el archivo "sleep.stderr" y solo STDERR de "time" entra en "time.txt"


2
Gracias, eso responde precisamente a mi pregunta. Si entendí correctamente, ¿el resultado del comando de tiempo se puede obtener de stderr?
ed82

77
Sí, pero debe ponerlo entre llaves, de lo contrario la redirección será parte del comando que timeevalúa.
Enero

55
@Daniel Siempre puedes redirigir la salida del comando interno por separado (es decir, {time sleep 1 2> sleepStdErr.txt;} 2> time.txt) y eso solo te proporcionaría la salida de tiempo. No estoy seguro de si hay una manera de obtenerlo independientemente de lo contrario.
gms7777

10
Si desea utilizar el tiempo con algo como grep que se lee en stdout intente { time sleep 1; } 2>&1 | grep real. Esto envía stderr a stdout que grep puede leer.
clayzermk1

9
NO olvides el ';' antes de cerrar '}', NO funcionará sin (lo hice, y ... me pregunto por qué no funciona :))
THESorcerer

38

Envolver time y el comando que está sincronizando en un conjunto de paréntesis.

Por ejemplo, los siguientes tiempos lsy escribe el resultado lsy los resultados del tiempo en outfile:

$ (time ls) > outfile 2>&1

O, si desea separar la salida del comando de la salida capturada de time:

$ (time ls) > ls_results 2> time_results

12
No es necesario introducir una subshell aquí.
Enero

1
@ sampson-chen Eso solo funciona porque ls no escribe nada para stderr ¿verdad? ¿Cómo "separaría" la salida de 'tiempo' de la del comando a ejecutar si el comando escribe tanto en stdout como en stderr?
David Doria el

36

Sencillo. La timeutilidad GNU tiene una opción para eso.

Pero debe asegurarse de no estar utilizando el timecomando incorporado de su shell , ¡al menos el bashincorporado no proporciona esa opción! Es por eso que necesita dar la ruta completa de la timeutilidad:

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

También puede usar el no incorporado sin especificar la ruta completa: stackoverflow.com/questions/29540540/…
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

14

Si le preocupa la salida de error del comando, puede separarlos de esta manera mientras sigue usando el comando de tiempo incorporado.

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

o

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

Como ve, los errores del comando van a un archivo (ya que stderrse usa para time).

Desafortunadamente, no puede enviarlo a otro identificador (como 3>&2) ya que eso ya no existirá fuera del{...}

Dicho esto, si puedes usar el tiempo GNU, solo haz lo que @Tim Ludwinski dijo.

\time -o time.log command

8

Dado que la salida del comando 'tiempo' es salida de error, rediríjalo ya que la salida estándar sería más intuitiva para realizar un procesamiento adicional.

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

6

Si está utilizando el tiempo GNU en lugar del bash incorporado, intente

time -o outfile command

(Nota: el formato de tiempo GNU es un poco diferente al bash incorporado).


1
Esto gracias. Y puede usar \time -o outfile command(con ``) para usar GNU en lugar de incorporado.
Marque el

3
&>out time command >/dev/null

en tu caso

&>out time sleep 1 >/dev/null

luego

cat out

3
Idea elegante, pero lleva a que el shell no use su comando incorporado. Si no tiene un timebinario real instalado, outcontendrá algo como bash: time: command not found.
scy

Además, el formato para el tiempo GNU no es el mismo que el bash incorporado, lo que causa problemas para el análisis automático.
Guss

3

Terminé usando:

/usr/bin/time -ao output_file.txt -f "Operation took: %E" echo lol
  • Donde se agrega "a"
  • Donde "o" es procesado por el nombre del archivo para adjuntar a
  • Donde "f" es formato con una sintaxis similar a printf
  • Donde "% E" produce 0:00:00; horas: minutos: segundos
  • Tuve que invocar / usr / bin / time porque el "tiempo" bash lo estaba pisoteando y no tiene las mismas opciones
  • Solo estaba tratando de obtener la salida al archivo, no es lo mismo que 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

Esto tiene el beneficio de no generar subcapas, y la tubería final tiene su stderr restaurado al stderr real.


0

Si no desea tocar el proceso original 'stdout y stderr, puede redirigir stderr al descriptor de archivo 3 y viceversa:

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

Puede usar eso para un contenedor (por ejemplo, para cronjobs) para monitorear tiempos de ejecución:

#!/bin/bash

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

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

0

Si está usando csh, puede usar:

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

Por ejemplo:

/usr/bin/time --output=outtime.txt -p csh -c 'cat file'
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.