¿Por qué time ls | grep real
sale esto?
real 0m0.002s
user 0m0.000s
sys 0m0.002s
en lugar de solo
real 0m0.002s
si escribo
echo -e 'real\t0m0.002s\nuser\t0m0.000s\nsys\t0m0.002s\n' | grep real
Obtengo lo que espero, es decir
real 0m0.002s
Descubrí que esto funciona
(time ls) 2>&1 > /dev/null | grep real
¿Qué hace este comando?
Respuesta1
¿Por qué time ls | grep real
no funciona como se esperaba?
time
es una bash
palabra reservada y se comporta de manera diferente a /usr/bin/time
.
Si la palabra de tiempo reservado precede a una canalización, se informa el tiempo transcurrido, así como el tiempo consumido por el usuario y el sistema en su ejecución.cuando termina el oleoducto.
Fuentebash(1): GNU Bourne-Again SHell - página de manual de Linux
Además, time
las salidas son de error estándar, no de salida estándar.
Utilice el siguiente comando:
(time ls) 2>&1 >/dev/null | grep real
Notas:
El
(
y)
agrupa los comandostime
yls
(para que estos comandos se evalúen primero)2>&1 >/dev/null
primero redirige stderr a stdout (que es la tubería) y luego redirige stdout a/dev/null
.Entonces stderr va a la tubería y stdout no va a ninguna parte.
Otras lecturas
- Un índice AZ de la línea de comando Bash para Linux- Una excelente referencia para todo lo relacionado con la línea de comandos de Bash.
- soportes- Usar paréntesis para agrupar y expandir expresiones.
- redirección de sintaxis- Redirección y Sustitución de Procesos.
- Manual de referencia de Bash: redirecciones
- Tutorial ilustrado de redirección [Bash Hackers Wiki]
Respuesta2
Sí, funciona, pero requiere un poco de redirección de E/S :)
$ exec 3>&1 4>&2
{ time sleep 1 1>&3 2>&4; } 2>&1 |
grep 'real'
exec 3>&- 4>&-
Producción :
real 0m1,003s
LeerPreguntas frecuentes sobre bash n.º 32yTutorial de redirección de E/S
Una forma bastante más sencilla:
$ TIMEFORMAT=%R
$ time sleep 1
1,003
Respuesta3
Dos cuestiones aquí.
Primero y más importante, "time" envía su salida a stderr (error estándar), no a stdout, para que no sea capturada por los comandos de redirección normales a menos que tome medidas especiales.
En segundo lugar, el tiempo no es un programa normal sino un comando especial incorporado interpretado directamente por el shell (para shells como bash, csh, tcsh, etc.). Por lo tanto, funciona de una manera no estándar y multiplica el resto de la línea de comandos (a menos que esté utilizando un shell muy inusual).
Entonces, para obtener el resultado que deseas (usando bash), necesitas usar:
(time ls) 2>&1 | grep real
Esto ejecutará "ls" en una subcapa y cronometrárálo [(tiempo ls)], envía el error estándar a la salida estándar[ 2>&1 ]y luego envía el estándar a "grep" [|grep].
La última parte que usó ">?dev/null" descarta la salida normal del comando ls en sí, en caso de que incluya la palabra "real".
Respuesta4
Parece que time
escribe directamente en la consola y no en stdout
, lo que significa que la salida del comando o canalización no se ve afectada al agregar time
.
Por lo tanto, grep
nunca ve el informe de tiempo, que en cualquier caso se genera después de que grep
se completa, ya que todo el proceso está cronometrado.