¿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.