C'è un modo per verificare quale numero di riga di uno bash
script viene eseguito "in questo momento"?
L'uso bash -x script.sh
sembra promettente; tuttavia, devo ottenere il numero di riga corrente.
C'è un modo per verificare quale numero di riga di uno bash
script viene eseguito "in questo momento"?
L'uso bash -x script.sh
sembra promettente; tuttavia, devo ottenere il numero di riga corrente.
Risposte:
Sì, c'è un modo.
Esiste una matrice di numeri di riga in cui è stata chiamata una funzione.
Definisci questa funzione:
f(){ echo "${BASH_LINENO[-2]}"; }
E chiama f
in qualsiasi linea desideri il numero di linea, ad esempio:
#!/bin/bash
f(){ echo "${BASH_LINENO[-2]}"; }
f
echo next1
f
echo next2
f
echo next 3
f
Stampa:
6
next 1
9
next 2
12
next 3
15
Potrebbe essere espanso per mostrare la scia di funzioni chiamate:
#!/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
Che stamperà:
$ ./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
Si noti che sopra l' echo "$LINENO"
uscita è sempre la stessa (7 in questo caso).
Ecco una soluzione che prende in prestito parti delle risposte di l0b0 e DopeGhoti (e, in misura minore, di sorontar ). Come quelle risposte, la mia usa $LINENO
per scoprire il numero di riga; a differenza di loro, utilizzo trap
per attivare la segnalazione. Il trap
comando di bash è descritto in bash (1) :
trap [-lp] [[arg] sigspec ...]
Il comando arg deve essere letto ed eseguito quando la shell riceve segnali sigspec . ... ︙
... Se un sigspec è DEBUG , il comando arg viene eseguito prima di ogni semplice comando ,for
comando,case
comando,select
comando, ognifor
comando aritmetico e prima che il primo comando venga eseguito in una funzione shell ...
Quindi questo 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))
$
esegue il printf "%3d: " "$LINENO"
comando prima di ogni comando nello script e produce questo output:
$ ./myscript 3: Mer, 05 apr 2017 10:16:17 4: 5: Mer, 05 apr 2017 10:16:47 7: 8: Mer, 05 apr 2017 10:16:58 10: totale 4 -rwxr-xr-x 1 myusername mygroup 221 5 aprile 10:01 myscript -rwxr-xr-x 1 myusername mygroup 252 5 aprile 10:01 myscript2 -rw-r - r-- 1 myusername mygroup 132 5 aprile 09:59 myscript2.log -rw-r - r-- 1 myusername mygroup 45 5 aprile 08:34 other_file 11: 13: myscript 14: -rwxr-xr-x 1 myusername mygroup 221 5 aprile 10:01 myscript 11: 13: myscript2 14: -rwxr-xr-x 1 myusername mygroup 252 5 aprile 10:01 myscript2 11: 13: myscript2.log 14: -rw-r - r-- 1 myusername mygroup 132 5 aprile 09:59 myscript2.log 11: 13: altro_file 14: -rw-r - r-- 1 myusername mygroup 45 5 aprile 08:34 other_file 17: 17: 19: i = 0 19: Mer, 05 apr 2017 10:16:59 17: 17: 19: i = 1 19: Mer, 05 apr 2017 10:16:59 17: 17: 19: i = 2 19: Mer, 05 apr 2017 10:16:59 17: 17: 22: 42 $
Appunti:
sleep
, che si estende sulle righe di script 6 e 7, è riportato come riga 7.for f in *
) viene riportata una volta prima di ogni iterazione di quel for
ciclo.echo "$f"
e ls -ld "$f"
sono riportati correttamente sulle rispettive righe (13 e 14).for ((i=0; i<3; i++))
) viene riportata due volte
prima di ogni iterazione di quel for
loop e due volte più dopo l'ultima iterazione.set -x
, LINENO
e PS4
(che sono specificati dallo standard POSIX), DEBUG trap
è un'estensione bash e non funzionerà in tutte le shell.trap
può eseguire qualsiasi comando (i) e non si limita a scrivere nell'output standard dello script o in un errore standard.La domanda dice: «controlla quale numero di riga di uno script bash viene eseguito“ proprio ora ”» senza specificare un'interfaccia utente. Un altro approccio è quello di scrivere continuamente il numero di riga corrente in un file di registro:
$ diff myscript myscript2 2C2 <trap 'printf "% 3d:" "$ LINENO"' DEBUG --- > exec 6> myscript2.log && trap 'printf "% 3d \ n" "$ LINENO"> & 6' DEBUG $ ./myscript2 Mer, 05 apr 2017 10:23:50 Mer, 05 apr 2017 10:24:20 Mer, 05 apr 2017 10:24:31 totale 4 -rwxr-xr-x 1 myusername mygroup 221 5 aprile 10:01 myscript -rwxr-xr-x 1 myusername mygroup 252 5 aprile 10:01 myscript2 -rw-r - r-- 1 myusername mygroup 24 apr 5 10:23 myscript2.log -rw-r - r-- 1 myusername mygroup 45 5 aprile 08:34 other_file MyScript -rwxr-xr-x 1 myusername mygroup 221 5 aprile 10:01 myscript MyScript2 -rwxr-xr-x 1 myusername mygroup 252 5 aprile 10:01 myscript2 myscript2.log -rw-r - r-- 1 myusername mygroup 60 5 aprile 10:23 myscript2.log un_altro_file -rw-r - r-- 1 myusername mygroup 45 5 aprile 08:34 other_file i = 0 Mer, 05 apr 2017 10:24:31 i = 1 Mer, 05 apr 2017 10:24:31 i = 2 Mer, 05 apr 2017 10:24:31 42 $
Possiamo monitorare l'esecuzione di questo script monitorando il contenuto del myscript2.log
file da un altro terminale. Ad esempio, durante il secondo sleep
,
$ tail myscript2.log
3
4
5
7
#!/bin/bash -x
Aggiungi quella "-x" all'inizio del tuo script. Quindi, ogni volta che esegui lo script, viene ripetuta la riga che esegue lo script. come un albero di esecuzione della tua sceneggiatura.