Czy istnieje sposób, aby sprawdzić, która linia numer o bash
skrypt jest wykonywany „teraz”?
Korzystanie bash -x script.sh
wygląda obiecująco; muszę jednak uzyskać bieżący numer linii.
źródło
Czy istnieje sposób, aby sprawdzić, która linia numer o bash
skrypt jest wykonywany „teraz”?
Korzystanie bash -x script.sh
wygląda obiecująco; muszę jednak uzyskać bieżący numer linii.
Połącz xtrace
z PS4
wewnątrz skryptu:
$ cat test.sh
#!/usr/bin/env bash
set -x
PS4='+${LINENO}: '
sleep 1m
sleep 1d
$ timeout 5 ./test.sh
+3: PS4='+${LINENO}: '
+5: sleep 1m
lub w powłoce nadrzędnej :
$ cat test.sh
sleep 1m
sleep 1d
$ export PS4='+${LINENO}: '
$ timeout 5 bash -x ./test.sh
+1: sleep 1m
Tak, jest sposób.
Istnieje tablica numerów linii, w których wywołano funkcję.
Zdefiniuj tę funkcję:
f(){ echo "${BASH_LINENO[-2]}"; }
I dzwoń f
na dowolną linię, na którą chcesz uzyskać numer linii, na przykład:
#!/bin/bash
f(){ echo "${BASH_LINENO[-2]}"; }
f
echo next1
f
echo next2
f
echo next 3
f
Wydrukuje:
6
next 1
9
next 2
12
next 3
15
Można go rozszerzyć, aby pokazać szereg funkcji o nazwie:
#!/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
Który wydrukuje:
$ ./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
Zauważ, że powyżej echo "$LINENO"
wyjście jest zawsze takie samo (w tym przypadku 7).
Oto rozwiązanie, które pożycza części odpowiedzi L0b0 i DopeGhoti (oraz, w mniejszym stopniu, odpowiedzi Sorontara ). Podobnie jak te odpowiedzi, moje używa $LINENO
do odkrycia numeru linii; w przeciwieństwie do nich, używam trap
do uruchamiania raportowania. trap
Polecenie bash opisano w bash (1) :
trap [-lp] [[arg] sigspec ...]
Polecenie arg należy odczytać i wykonać, gdy powłoka odbierze sygnał (-y) sigspec . … ︙
… Jeśli sigspec to DEBUG , polecenie arg jest wykonywane przed każdą prostą komendą ,for
komendą,case
komendą,select
komendą, każdąfor
komendą arytmetyczną i przed wykonaniem pierwszej komendy w funkcji powłoki…
Więc ten skrypt:
$ 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))
$
uruchamia printf "%3d: " "$LINENO"
polecenie przed każdym poleceniem w skrypcie i generuje następujące dane wyjściowe:
$ ./myscript 3: śr., 05 kwietnia 2017 10:16:17 4: 5: śr., 05 kwietnia 2017 10:16:47 7: 8: śr., 05 kwietnia 2017 10:16:58 10: łącznie 4 -rwxr-xr-x 1 moja nazwa użytkownika moja grupa 221 5 kwietnia 10:01 mój skrypt -rwxr-xr-x 1 moja nazwa użytkownika moja grupa 252 5 kwietnia 10:01 myscript2 -rw-r - r-- 1 moja nazwa użytkownika moja grupa 132 kwi 5 09:59 myscript2.log -rw-r - r-- 1 moja nazwa użytkownika moja grupa 45 kwietnia 5 08:34 inny_plik 11: 13: myscript 14: -rwxr-xr-x 1 moja nazwa użytkownika moja grupa 221 5 kwietnia 10:01 myscript 11: 13: myscript2 14: -rwxr-xr-x 1 moja nazwa użytkownika moja grupa 252 5 kwietnia 10:01 myscript2 11: 13: myscript2.log 14: -rw-r - r-- 1 moja nazwa użytkownika moja grupa 132 kwi 5 09:59 myscript2.log 11: 13: inny_plik 14: -rw-r - r-- 1 moja nazwa użytkownika moja grupa 45 kwietnia 5 08:34 inny_plik 17: 17: 19: i = 0 19: śr., 05 kwietnia 2017 10:16:59 17: 17: 19: i = 1 19: śr., 05 kwietnia 2017 10:16:59 17: 17: 19: i = 2 19: śr., 05 kwietnia 2017 10:16:59 17: 17: 22: 42 $
Uwagi:
sleep
, który obejmuje wiersze 6 i 7 skryptu, jest zgłaszany jako wiersz 7.for f in *
) jest zgłaszany raz przed każdą iteracją tej for
pętli.echo "$f"
i ls -ld "$f"
są poprawnie zgłaszane na odpowiednich liniach (13 i 14).for ((i=0; i<3; i++))
) jest zgłaszany dwa razy
przed każdą iteracją tej for
pętli i jeszcze dwa razy po ostatniej iteracji.set -x
, LINENO
i PS4
(które są określone przez standard POSIX), DEBUG trap
jest rozszerzeniem bash i nie będzie działać we wszystkich muszli.trap
może uruchamiać dowolne polecenia i nie ogranicza się do zapisywania na standardowe wyjście skryptu lub standardowy błąd.Pytanie brzmi: „sprawdź, który numer wiersza skryptu bash jest wykonywany„ teraz ”” bez określania interfejsu użytkownika. Innym podejściem jest ciągłe zapisywanie bieżącego numeru wiersza w pliku dziennika:
$ diff myscript myscript2 2c2 <pułapka 'printf "% 3d:" "$ LINENO"' DEBUG --- > exec 6> myscript2.log && trap 'printf "% 3d \ n" "$ LINENO"> & 6' DEBUG $ ./myscript2 Śr., 05 kwietnia 2017 10:23:50 Śr., 05 kwietnia 2017 10:24:20 Śr., 05 kwietnia 2017 10:24:31 razem 4 -rwxr-xr-x 1 moja nazwa użytkownika moja grupa 221 5 kwietnia 10:01 mój skrypt -rwxr-xr-x 1 moja nazwa użytkownika moja grupa 252 5 kwietnia 10:01 myscript2 -rw-r - r-- 1 moja nazwa użytkownika moja grupa 24 kwietnia 5 10:23 myscript2.log -rw-r - r-- 1 moja nazwa użytkownika moja grupa 45 kwietnia 5 08:34 inny_plik mój skrypt -rwxr-xr-x 1 moja nazwa użytkownika moja grupa 221 5 kwietnia 10:01 mój skrypt myscript2 -rwxr-xr-x 1 moja nazwa użytkownika moja grupa 252 5 kwietnia 10:01 myscript2 myscript2.log -rw-r - r-- 1 moja nazwa użytkownika moja grupa 60 kwietnia 5 10:23 myscript2.log inny_plik -rw-r - r-- 1 moja nazwa użytkownika moja grupa 45 kwietnia 5 08:34 inny_plik i = 0 Śr., 05 kwietnia 2017 10:24:31 i = 1 Śr., 05 kwietnia 2017 10:24:31 i = 2 Śr., 05 kwietnia 2017 10:24:31 42 $
Możemy monitorować wykonanie tego skryptu, monitorując zawartość myscript2.log
pliku z innego terminala. Na przykład, podczas drugiego sleep
,
$ tail myscript2.log
3
4
5
7
Możesz echo $LINENO
w skrypcie, który powinien wypisać dowolny wiersz, w którym znajduje się polecenie.
#!/bin/bash
echo $LINENO
$ ./foo.sh
2
#!/bin/bash -x
Dodaj „-x” na początku skryptu. Następnie za każdym razem, gdy wykonujesz skrypt, będzie on odzwierciedlał linię wykonywaną przez skrypt. jak drzewo wykonania skryptu.