Tengo un script que mide cuánto tiempo se ejecuta un comando.
Necesita el time
comando "real" , es decir, un binario, por ejemplo, en /usr/bin/time
(ya que bash-built-in no tiene la -f
bandera).
A continuación, un script simplificado que se puede depurar:
#!/bin/bash
TIMESEC=$(echo blah | ( /usr/bin/time -f %e grep blah >/dev/null ) 2>&1 | awk -F. '{print $1}')
echo ABC--$TIMESEC--DEF
if [ "$TIMESEC" -eq 0 ] ; then
echo "we are here!"
fi
Guardar como "test.sh" y ejecutar:
$ bash test.sh
ABC--0--DEF
we are here!
Entonces funcionó.
Ahora, intentemos depurar esto agregando "-x" a la línea de comando bash:
$ bash -x test.sh
++ echo blah
++ awk -F. '{print $1}'
+ TIMESEC='++ /usr/bin/time -f %e grep blah
0'
+ echo ABC--++ /usr/bin/time -f %e grep blah 0--DEF
ABC--++ /usr/bin/time -f %e grep blah 0--DEF
+ '[' '++ /usr/bin/time -f %e grep blah
0' -eq 0 ']'
test.sh: line 10: [: ++ /usr/bin/time -f %e grep blah
0: integer expression expected
¿Por qué este script se rompe cuando usamos "-x" y funciona bien sin él?
bash
shell-script
Tomasz Chmielewski
fuente
fuente
-x
on, la$()
construcción está obteniendo la-x
salida incluida como parte de su valor resultante. Sin embargo, no sé si ese es el comportamiento "esperado" o un error ... O tal vez es la subshell()
que realmente está dando la-x
salida.BASH_XTRACEFD
permite redirigir laset -x
salida a un lugar donde sea menos problemático.Respuestas:
El problema es esta línea:
donde está redirigiendo el error estándar para que coincida con la salida estándar. bash está escribiendo sus mensajes de rastreo en el error estándar, y está (por ejemplo) usando su construcción integrada
echo
junto con otras construcciones de shell, todo en el proceso bash.Si lo cambias a algo como
solucionará ese problema y quizás sea un compromiso aceptable entre el rastreo y el trabajo:
fuente
También puede simplemente soltar la subshell. aparentemente son las conchas anidadas las que terminan molestándose unas a otras:
Si lo haces:
... terminas con el subshell lanzado para manejar esa sección de la tubería que aloja el subshell. Debido a que el shell sin redirecciona incluso la salida de depuración del subshell dentro (como también lo haría para cualquier otro tipo de
{
comando compuesto; } >redirect
que pueda elegir usar) a su sección de la tubería, termina mezclando flujos. Tiene que ver con el orden de redireccionamiento.En cambio, si simplemente primera redirección solamente la salida de error de los comandos que se está tratando de calibre, y dejar que marca la salida de la cáscara de acogida a stderr, que no terminan con el mismo problema.
y entonces...
... el shell del host es libre de continuar escribiendo su stderr donde le plazca mientras solo redirige la salida de los comandos que llama a la tubería.
Para esa materia...
fuente