¿Hay alguna manera de verificar qué número de línea de un bash
script se está ejecutando "en este momento"?
Usar bash -x script.sh
looks prometedores; Sin embargo, necesito obtener el número de línea actual.
fuente
¿Hay alguna manera de verificar qué número de línea de un bash
script se está ejecutando "en este momento"?
Usar bash -x script.sh
looks prometedores; Sin embargo, necesito obtener el número de línea actual.
Sí, hay una manera.
Hay una serie de números de línea donde se ha llamado a una función.
Defina esta función:
f(){ echo "${BASH_LINENO[-2]}"; }
Y llame f
a cualquier línea que desee el número de línea, por ejemplo:
#!/bin/bash
f(){ echo "${BASH_LINENO[-2]}"; }
f
echo next1
f
echo next2
f
echo next 3
f
Imprimirá:
6
next 1
9
next 2
12
next 3
15
Se podría ampliar para mostrar el rastro de funciones llamadas:
#!/bin/bash
f(){
for ((i=${#BASH_LINENO[@]}-1;i>=0;i--)); do
printf '<%s:%s> ' "${FUNCNAME[i]}" "${BASH_LINENO[i]}";
done
echo "$LINENO"
}
SomeOtherFunction(){ echo -n "test the line numbering: "; f; }
f
echo next 1
echo -n " This line numbering: "; f
SomeOtherFunction
echo next 2
echo -n " This line numbering: "; f
SomeOtherFunction
echo next 3
echo -n " This line numbering: "; f
Que imprimirá:
$ ./script
<main:0> <f:12> 7
next 1
This line numbering: <main:0> <f:15> 7
test the line numbering: <main:0> <SomeOtherFunction:16> <f:10> 7
next 2
This line numbering: <main:0> <f:19> 7
test the line numbering: <main:0> <SomeOtherFunction:20> <f:10> 7
next 3
This line numbering: <main:0> <f:23> 7
Tenga en cuenta que por encima de la echo "$LINENO"
salida es siempre la misma (7 en este caso).
Aquí hay una solución que toma prestadas partes de las respuestas de l0b0 y DopeGhoti (y, en menor medida, las de sorontar ). Al igual que esas respuestas, la mía usa $LINENO
para descubrir el número de línea; a diferencia de ellos, uso trap
para activar los informes. El trap
comando de bash se describe en bash (1) :
trap [-lp] [[arg] sigspec ...]
El comando arg debe leerse y ejecutarse cuando el shell recibe señal (es) sigspec . ... ︙
... Si un sigspec es DEBUG , el comando arg se ejecuta antes de cada comando simple ,for
comando,case
comando,select
comando, cadafor
comando aritmético , y antes de que el primer comando se ejecute en una función de shell ...
Entonces este script:
$ cat -n myscript
1 #!/bin/bash
2 trap 'printf "%3d: " "$LINENO"' DEBUG
3 date
4 sleep 30
5 date
6 sleep \
7 11
8 date
9
10 ls -l
11 for f in *
12 do
13 echo "$f" &&
14 ls -ld "$f"
15 done
16
17 for ((i=0; i<3; i++))
18 do
19 echo "i = $i"; date
20 done
21
22 echo $((5+25+12))
$
ejecuta el printf "%3d: " "$LINENO"
comando antes de cada comando en el script y produce esta salida:
$ ./myscript 3: Mié, 05 de abril de 2017 10:16:17 a.m. 4: 5: mié, 05 de abril de 2017 10:16:47 a.m. 7: 8: mié, 05 de abril de 2017 10:16:58 a.m. 10: total 4 -rwxr-xr-x 1 myusername mygroup 221 5 de abril 10:01 myscript -rwxr-xr-x 1 myusername mygroup 252 5 de abril 10:01 myscript2 -rw-r - r-- 1 myusername mygroup 132 5 de abril 09:59 myscript2.log -rw-r - r-- 1 myusername mygroup 45 5 de abril 08:34 otro_archivo 11: 13: MyScript 14: -rwxr-xr-x 1 myusername mygroup 221 5 de abril 10:01 myscript 11: 13: myscript2 14: -rwxr-xr-x 1 myusername mygroup 252 5 de abril 10:01 myscript2 11: 13: myscript2.log 14: -rw-r - r-- 1 myusername mygroup 132 5 de abril 09:59 myscript2.log 11: 13: otro_archivo 14: -rw-r - r-- 1 myusername mygroup 45 5 de abril 08:34 otro_archivo 17: 17: 19: i = 0 19: mié, 05 de abril de 2017 10:16:59 a.m. 17: 17: 19: i = 1 19: mié, 05 de abril de 2017 10:16:59 a.m. 17: 17: 19: i = 2 19: mié, 05 de abril de 2017 10:16:59 a.m. 17: 17: 22: 42 PS
Notas:
sleep
, que abarca las líneas de guión 6 y 7, se informa como la línea 7.for f in *
) se informa una vez antes de cada iteración de ese for
ciclo.echo "$f"
y ls -ld "$f"
se informan correctamente en sus respectivas líneas (13 y 14).for ((i=0; i<3; i++))
) se informa dos veces
antes de cada iteración de ese for
ciclo, y dos veces más después de la última iteración.set -x
, LINENO
y PS4
(que se especifican en el estándar POSIX), DEBUG trap
es una extensión bash y no funcionará en todos los shells.trap
puede ejecutar cualquier comando (s), y no está restringido a escribir en la salida estándar del script o error estándar.La pregunta dice: «compruebe qué número de línea de un script bash se está ejecutando" en este momento "» sin especificar una interfaz de usuario. Otro enfoque es escribir continuamente el número de línea actual en un archivo de registro:
$ diff myscript myscript2 2c2 <trap 'printf "% 3d:" "$ LINENO"' DEBUG --- > exec 6> myscript2.log && trap 'printf "% 3d \ n" "$ LINENO"> & 6' DEPURACIÓN $ ./myscript2 Mié, 05 de abril de 2017 10:23:50 a.m. Mié, 05 de abril de 2017 10:24:20 a.m. Mié, 05 de abril de 2017 10:24:31 a.m. total 4 -rwxr-xr-x 1 myusername mygroup 221 5 de abril 10:01 myscript -rwxr-xr-x 1 myusername mygroup 252 5 de abril 10:01 myscript2 -rw-r - r-- 1 myusername mygroup 24 abr 5 10:23 myscript2.log -rw-r - r-- 1 myusername mygroup 45 5 de abril 08:34 otro_archivo MyScript -rwxr-xr-x 1 myusername mygroup 221 5 de abril 10:01 myscript myscript2 -rwxr-xr-x 1 myusername mygroup 252 5 de abril 10:01 myscript2 myscript2.log -rw-r - r-- 1 myusername mygroup 60 5 de abril 10:23 myscript2.log otro_archivo -rw-r - r-- 1 myusername mygroup 45 5 de abril 08:34 otro_archivo i = 0 Mié, 05 de abril de 2017 10:24:31 a.m. i = 1 Mié, 05 de abril de 2017 10:24:31 a.m. i = 2 Mié, 05 de abril de 2017 10:24:31 a.m. 42 PS
Podemos monitorear la ejecución de este script al monitorear el contenido del myscript2.log
archivo desde otro terminal. Por ejemplo, durante el segundo sleep
,
$ tail myscript2.log
3
4
5
7
Puede echo $LINENO
hacerlo en un script y debería generar cualquier línea en la que se encuentre ese comando.
#!/bin/bash
echo $LINENO
$ ./foo.sh
2
#!/bin/bash -x
Agregue ese "-x" al comienzo de su secuencia de comandos. Luego, cada vez que ejecute el script, se hará eco de la línea que ejecuta su script. como un árbol de ejecución de tu script.