Para saber cuánto tiempo tardan ciertas operaciones dentro de un script Bash (v4 +), me gustaría analizar el resultado del timecomando "por separado" y (en última instancia) capturarlo dentro de una variable Bash ( let VARNAME=...).
Ahora, estoy usando time -f '%e' ...(o más bien command time -f '%e' ...debido al Bash incorporado), pero dado que ya redirijo la salida del comando ejecutado, realmente estoy perdido en cuanto a cómo capturaría la salida del timecomando. Básicamente, el problema aquí es separar la salida de timela salida de los comandos ejecutados.
Lo que quiero es la funcionalidad de contar la cantidad de tiempo en segundos (enteros) entre el inicio de un comando y su finalización. No tiene que ser el timecomando o el respectivo incorporado.
Editar: dadas las dos respuestas útiles a continuación, quería agregar dos aclaraciones.
- No quiero tirar la salida del comando ejecutado, pero realmente no importará si termina en stdout o stderr.
- Preferiría un enfoque directo sobre uno indirecto (es decir, capturar la salida directamente en lugar de almacenarla en archivos intermedios).
La solución que utilizo datehasta ahora se cierra a lo que quiero.
fuente

fork(),execvp()ywait3()/wait4(). En última instancia, esto es lo que están haciendo el tiempo y los amigos. No conozco una manera simple de hacerlo en bash / perl sin redirigir a un archivo o enfoque similar.Respuestas:
Para obtener la salida de
timeen una var, use lo siguiente:También puede solicitar un solo tipo de hora, por ejemplo, utime:
Para obtener el tiempo que también puede usar
date +%s.%N, tómelo antes y después de la ejecución y calcule la diferencia:fuente
DIFF=$((END-START)), haciendo uso de las expresiones aritméticas. :) ... gracias por la respuesta. +1.%Nen el código de binfalse), necesitabccálculos más sofisticados.time (cmd) 2> somethingfunciona para redirigir la salida de temporizaciónfile, no está destinado a (según la documentación), no lo hace en otros shells dondetimehay una palabra clave y podría considerarse como un error . No confiaría en él, ya que puede no funcionar en futuras versiones debash.En bash, el resultado de la
timeconstrucción va a su error estándar, y puede redirigir el error estándar de la tubería que afecta. Así que vamos a empezar con un comando que escribe a sus streamas de salida y de error:sh -c 'echo out; echo 1>&2 err'. Para no mezclar la secuencia de error del comando con la salida detime, podemos desviar temporalmente la secuencia de error del comando a un descriptor de archivo diferente:Esto escribe
outen fd 1,erren fd 3 y los tiempos en fd 2:Sería más agradable tenerlo
erren fd 2 y las veces en fd 3, por lo que los intercambiamos, lo cual es engorroso porque no hay una forma directa de intercambiar dos descriptores de archivo:Esto muestra cómo puede postprocesar la salida del comando, pero si desea capturar tanto la salida del comando como sus tiempos, debe trabajar más duro. Usar un archivo temporal es una solución. De hecho, es la única solución confiable si necesita capturar tanto el error estándar del comando como su salida estándar. Pero de lo contrario, puede capturar todo el resultado y aprovechar el hecho de que
timetiene un formato predecible (si lo usatime -ppara obtener el formato POSIX o laTIMEFORMATvariable específica de bash ).Si solo le importa el tiempo del reloj de pared, la ejecución
dateantes y después es una solución simple (si es un poco más imprecisa debido al tiempo extra dedicado a cargar el comando externo).fuente
Con el tiempo, la salida del comando sale en stdout y el tiempo sale en stderr. Entonces, para separarlos, puedes hacer:
Pero, ahora el tiempo está en un archivo. No creo que Bash pueda poner stderr en una variable directamente. Si no le importa redirigir la salida del comando a alguna parte, puede hacer lo siguiente:
Cuando haga esto, la salida del comando estará activada
outputfiley el tiempo que tardó en ejecutarse$FOO.fuente
timeescrituras de stderr, pero no me di cuenta de que fusionaría stdout y stderr del comando ejecutado en su stdout. Pero, en general, ¿no hay un método directo (es decir, sin archivo intermedio)? +1.timeno combina sus comandosstdoutystderr. La forma en que lo mostré suponía que solo necesitabas la salida estándar del comando. Comobashsolo almacenará lo que salgastdout, debe redirigir. En caso de que pueda soltar con seguridad el comando stderr: el tiempo siempre estará en la última línea de stderr. Si necesita las dos secuencias de salida de su comando, le sugiero que lo envuelva en otro script.Si está
bash(y nosh) y NO necesita una precisión de menos de un segundo, puede omitir la llamada pordatecompleto y hacerlo sin generar ningún proceso adicional, sin tener que separar la salida combinada y sin tener que capturar y analizar la salida de cualquier comando:fuente
Para ese propósito, probablemente sea mejor usar
times(quetime) en elbashque imprime el usuario acumulado y los tiempos del sistema para el shell y para los procesos ejecutados desde el shell, por ejemplo use:Ver:
help -m timespara más información.fuente
Al poner todas las respuestas anteriores juntas, cuando en OSX
puedes hacer como
fuente
Instalar
/bin/time(por ejemplopacman -S time)Entonces, en lugar de error al intentar
-fmarcar:Realmente puedes usarlo:
Y obtenga lo que desea: tiempo en variable (ejemplo, usos
%epara el tiempo transcurrido real, para otras opciones de verificaciónman time):fuente
/usr/bin/timeen muchos sistemastimees un shell integrado en Bash (y presumiblemente otros shells), pero siempre quetimeesté la ruta al ejecutablePATH, podemos usarlocommand timepara asegurarnos de que estamos ejecutando el comando externo en lugar del incorporado.Solo como un aviso al trabajar con las declaraciones anteriores y especialmente teniendo en cuenta la respuesta de Grzegorz. Me sorprendió ver en mi sistema Ubuntu 16.04 Xenial estos dos resultados:
No tengo ningún alias establecido, por lo que no sé por qué sucede esto.
fuente
timeTambién es una cáscara incorporada.command, si desea asegurarse de que está ejecutando el comando incorporado, usebuiltin. No hay magia aquí. Utilícelohelppara descubrir los comandos disponibles otype <command>para determinar qué tipo<command>es (por ejemplo, un comando incorporado, un comando externo, una función o un alias).commandcomando. Lo cual es un hecho asegura que se llame a / usr / bin / time. Esto significa que las siguientes dos declaraciones son compatibles:$ command time -f %e sleep 4y$ /usr/bin/time -f %e sleepintente esto, ejecuta un comando simple con argumentos y pone los tiempos $ real $ user $ sys y conserva el código de salida.
Tampoco bifurca subcapas ni pisotea ninguna variable, excepto el sistema de usuario real, y no interfiere con la ejecución del script
p.ej
nota: solo mide el tiempo del comando simple, no una tubería, cuyos componentes se ejecutan en una subshell
Esta versión le permite especificar como $ 1 el nombre de las variables que deberían recibir las 3 veces:
p.ej
y puede ser útil si termina siendo llamado de forma recursiva, para evitar pisotear a veces; pero luego rus, etc., deben declararse locales en su uso.
http://blog.sam.liddicott.com/2016/01/timeing-bash-commands.html
fuente