Obtener el tiempo de ejecución del programa en el shell


Quiero ejecutar algo en un shell de Linux bajo unas pocas condiciones diferentes, y ser capaz de generar el tiempo de ejecución de cada ejecución.

Sé que podría escribir un script de perl o python que haría esto, pero ¿hay alguna forma de hacerlo en el shell? (que pasa a ser bash)

Author: ʞɔıu, 2008-12-22

9 answers

Usa la palabra clave incorporada time:

$ help time

time: time [-p] PIPELINE
    Execute PIPELINE and print a summary of the real time, user CPU time,
    and system CPU time spent executing PIPELINE when it terminates.
    The return status is the return status of PIPELINE.  The `-p' option
    prints the timing summary in a slightly different format.  This uses
    the value of the TIMEFORMAT variable as the output format.

Ejemplo:

$ time sleep 2
real    0m2.009s
user    0m0.000s
sys     0m0.004s
 470
Author: Robert Gamble,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-30 03:52:23

Puede obtener información mucho más detallada que el bash incorporado time (que Robert Gamble menciona) usando time(1). Normalmente, esto es /usr/bin/time.

Nota del editor: Para asegurarse de que está invocando la utilidad externa time en lugar de tu caparazón time palabra clave , invócala como /usr/bin/time.
time es una utilidad con mandato POSIX, pero la única opción que debe soportar es -p.
Plataformas específicas implementan plataformas específicas, extensiones no estándar: -vfunciona con la utilidad GNU, como se muestra a continuación (la pregunta está etiquetada linux ); la implementación de BSD/macOS usa-l para producir resultados similares - ver man 1 time.

Ejemplo de salida detallada:


$ /usr/bin/time -v sleep 1
       Command being timed: "sleep 1"
       User time (seconds): 0.00
       System time (seconds): 0.00
       Percent of CPU this job got: 1%
       Elapsed (wall clock) time (h:mm:ss or m:ss): 0:01.05
       Average shared text size (kbytes): 0
       Average unshared data size (kbytes): 0
       Average stack size (kbytes): 0
       Average total size (kbytes): 0
       Maximum resident set size (kbytes): 0
       Average resident set size (kbytes): 0
       Major (requiring I/O) page faults: 0
       Minor (reclaiming a frame) page faults: 210
       Voluntary context switches: 2
       Involuntary context switches: 1
       Swaps: 0
       File system inputs: 0
       File system outputs: 0
       Socket messages sent: 0
       Socket messages received: 0
       Signals delivered: 0
       Page size (bytes): 4096
       Exit status: 0

 108
Author: grepsedawk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-30 04:15:06
#!/bin/bash
START=$(date +%s)
# do something
# start your script work here
ls -R /etc > /tmp/x
rm -f /tmp/x
# your logic ends here
END=$(date +%s)
DIFF=$(( $END - $START ))
echo "It took $DIFF seconds"
 70
Author: David,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-07-12 09:30:40

Para una medición delta línea por línea, pruebe gnomon.

Una utilidad de línea de comandos, un poco como el ts de moreutils, para anteponer información de marca de tiempo a la salida estándar de otro comando. Útil para procesos de larga duración en los que desea un registro histórico de lo que está tomando tanto tiempo.

También puede usar las opciones --high y/o --medium para especificar un umbral de longitud en segundos, sobre el cual gnomon resaltará la marca de tiempo en rojo o amarillo. Y puedes hacer una algunas otras cosas también.

ejemplo

 32
Author: Adriano Resende,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-17 19:02:53

Si desea más precisión, use %N con date (y use bc para el diff, porque $(()) solo maneja enteros).

Aquí está cómo hacerlo:

start=$(date +%s.%N)
# do some stuff here
dur=$(echo "$(date +%s.%N) - $start" | bc)

printf "Execution time: %.6f seconds" $dur

Ejemplo:

start=$(date +%s.%N); \
  sleep 0.1s; \
  dur=$(echo "$(date +%s.%N) - $start" | bc); \
  printf "Execution time: %.6f seconds\n" $dur

Resultado:

Execution time: 0.104623 seconds
 16
Author: Benoit Duffez,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-08-28 13:48:31

Si tiene la intención de usar los tiempos más tarde para calcular, aprenda a usar la opción -f de /usr/bin/time para generar el código que ahorra tiempos. Aquí hay un código que usé recientemente para obtener y ordenar los tiempos de ejecución de toda una clase de programas de estudiantes:

fmt="run { date = '$(date)', user = '$who', test = '$test', host = '$(hostname)', times = { user = %U, system = %S, elapsed = %e } }"
/usr/bin/time -f "$fmt" -o $timefile command args...

Más tarde concatenado todos los archivos $timefile y canalizar la salida en un intérprete Lua. Puedes hacer lo mismo con Python o bash o cualquiera que sea tu sintaxis favorita. Me encanta esta técnica.

 13
Author: Norman Ramsey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-12-22 03:56:39

Si solo necesita precisión para el segundo, puede usar la variable builtin $SECONDS, que cuenta el número de segundos que el shell ha estado ejecutando.

while true; do
    start=$SECONDS
    some_long_running_command
    duration=$(( SECONDS - start ))
    echo "This run took $duration seconds"
    if some_condition; then break; fi
done
 8
Author: glenn jackman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-20 16:56:38

Puede usar time y subshell ():

time (
  for (( i=1; i<10000; i++ )); do
    echo 1 >/dev/null
  done
)

O en el mismo shell {}:

time {
  for (( i=1; i<10000; i++ )); do
    echo 1 >/dev/null
  done
}
 6
Author: Eduardo Cuomo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-18 21:09:17

El camino es

$ > g++ -lpthread perform.c -o per
$ > time ./per

La salida es > >

real    0m0.014s
user    0m0.010s
sys     0m0.002s
 2
Author: Robel Sharma,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-31 16:40:36