Dają ci ślad tego, co jest wykonywane. (Zobacz także „Wyjaśnienie” u dołu odpowiedzi).
Czasami trzeba kontrolować debugowanie w skrypcie. W takim razie, jak przypomniał mi Cheeto , możesz użyć:
set-x
To włącza debugowanie. Następnie możesz go ponownie wyłączyć za pomocą:
set+x
(Możesz sprawdzić bieżący stan śledzenia, analizując $-bieżące flagi dla x).
Ponadto powłoki generalnie udostępniają opcje „ -n” dla „braku wykonywania” i „ -v” dla trybu „gadatliwego”; możesz użyć ich w połączeniu, aby sprawdzić, czy powłoka uważa, że może wykonać twój skrypt - czasami przydatne, jeśli gdzieś masz niezrównoważony cytat.
Istnieje twierdzenie, że -xopcja „ ” w Bash różni się od innych powłok (patrz komentarze). Instrukcja Bash mówi:
-x
Wydrukuj ślad prostych poleceń, forpoleceń, casepoleceń, selectpoleceń i forpoleceń arytmetycznych oraz ich argumentów lub powiązanych list słów po ich rozwinięciu i przed wykonaniem. Wartość PS4zmiennej jest interpretowana, a wynikowa wartość jest wypisywana przed poleceniem i jego rozwiniętymi argumentami.
To wcale nie wydaje się wskazywać na inne zachowanie. Nie widzę żadnych innych odnośnych odniesień do „ -x” w instrukcji. Nie opisuje różnic w kolejności startowej.
Wyjaśnienie : W systemach takich jak typowy Linux, gdzie „ /bin/sh” jest dowiązaniem symbolicznym do „ /bin/bash” (lub gdziekolwiek zostanie znaleziony plik wykonywalny Bash), dwie linie poleceń osiągają równoważny efekt uruchamiania skryptu z włączonym śledzeniem wykonania. W innych systemach (na przykład Solaris i niektóre bardziej nowoczesne warianty Linuksa) /bin/shnie jest Bash, a dwie linie poleceń dałyby (nieco) różne wyniki. Przede wszystkim „ /bin/sh” byłby zdezorientowany przez konstrukcje w Bash, których w ogóle nie rozpoznaje. (W Solarisie /bin/shjest to powłoka Bourne'a; we współczesnym Linuksie jest to czasami Dash - mniejsza, bardziej ściśle zgodna tylko z POSIX-owa powłoka). Po wywołaniu z taką nazwą, linia „shebang” ( #!/bin/bash„vs '#!/bin/sh”
Podręcznik Bash zawiera sekcję o trybie Bash POSIX, który w przeciwieństwie do długotrwałej, ale błędnej wersji tej odpowiedzi (zobacz również komentarze poniżej), opisuje szczegółowo różnicę między 'Bash wywołany jako sh' a 'Bash wywołany jako' bash”.
Podczas debugowania (Bash) skryptu powłoki rozsądne i rozsądne będzie - nawet konieczne - użycie powłoki wymienionej w linii shebang z -xopcją. W przeciwnym razie możesz (będzie?) Uzyskać inne zachowanie podczas debugowania niż podczas uruchamiania skryptu.
Określił bashscenariusz. Uruchomienie skryptu bash w programie sh -xsprawi, że będzie się on zachowywał zupełnie inaczej! Zaktualizuj swoją odpowiedź.
lhunath
1
@lhunath: W jaki sposób „sh -x” (lub „bash -x”) powoduje, że skrypt zachowuje się zupełnie inaczej? Oczywiście przekazuje informacje o śledzeniu na stderr; to jest dane (choć nie zostało wspomniane w mojej odpowiedzi). Ale co jeszcze? Używam „bash” jako „sh” na Linuksie i MacOS X i nie zauważyłem poważnego problemu.
Jonathan Leffler
6
Istnieją różnice w uruchamianiu i w czasie wykonywania. Są w pełni udokumentowane w dystrybucji Bash.
TheBonsai
4
Oto link do dokumentu bash: gnu.org/software/bash/manual/bashref.html#Bash-Startup-Files 'Jeśli Bash jest wywoływany z nazwą sh, próbuje naśladować zachowanie startowe historycznych wersji sh as jak najściślej, przy jednoczesnym zachowaniu zgodności ze standardem posix ”
thethinman
6
I użyj podpowiedzi PS4, aby podać bardziej przydatne informacje, takie jak:export PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'
estani
28
Użyłem następujących metod do debugowania mojego skryptu.
set -epowoduje natychmiastowe zatrzymanie skryptu, jeśli jakikolwiek program zewnętrzny zwróci niezerowy kod zakończenia. Jest to przydatne, jeśli twój skrypt próbuje obsłużyć wszystkie przypadki błędów i gdzie niepowodzenie powinno zostać złapane.
set -x został wspomniany powyżej iz pewnością jest najbardziej użyteczną ze wszystkich metod debugowania.
set -n może być również przydatne, jeśli chcesz sprawdzić skrypt pod kątem błędów składniowych.
stracejest również przydatne, aby zobaczyć, co się dzieje. Szczególnie przydatne, jeśli sam nie napisałeś scenariusza.
Śledzenie skryptu (tj. Umieszczanie powłoki w powłoce wykonującej skrypt) jest dziwną metodą debugowania powłoki (ale może działać w przypadku ograniczonego zestawu problemów).
TheBonsai
1
Przyznaję, że jest to dziwne i bardzo rozwlekłe, ale jeśli ograniczysz wyjście strace do kilku wywołań systemowych, stanie się to przydatne.
1
Zauważ, że strace -fjest to potrzebne, jeśli chcesz również znaleźć błędy w procesach uruchomionych przez skrypt. (co sprawia, że jest wielokrotnie bardziej rozwlekły, ale nadal przydatny, jeśli ograniczysz go do wywołań systemowych, które Cię interesują).
Jednak uważam, że „standardowe” metody debugowania skryptów są nieefektywne, nieintuicyjne i trudne w użyciu. Dla osób przyzwyczajonych do wyrafinowanych debuggerów GUI, które umieszczają wszystko na wyciągnięcie ręki i sprawiają, że praca jest szybka w przypadku łatwych problemów (i możliwych w przypadku trudnych problemów), te rozwiązania nie są zbyt satysfakcjonujące.
Używam kombinacji DDD i bashdb. Pierwsza wykonuje drugą, a druga wykonuje skrypt. Zapewnia to interfejs użytkownika z wieloma oknami z możliwością przechodzenia przez kod w kontekście i przeglądania zmiennych, stosu itp., Bez ciągłego wysiłku umysłowego w celu utrzymania kontekstu w głowie lub ponownego wyświetlania źródła.
Właśnie odkryłem ddd dzięki twojej odpowiedzi. W Ubuntu 12.04.3 (64-bitowy) wersja apt-sources nie działa. Musiałem skompilować i zainstalować ze źródła, aby rozpocząć debugowanie skryptu bash. Instrukcje tutaj - askubuntu.com/questions/156906/ ... pomogły.
chronodekar
Tak, to jest problem. Rozwiązałem to jakiś czas temu za pomocą skryptów - `` dddbash '' instaluje / buduje DDD, usuwa starą wersję, jeśli jest nieprawidłowa, instaluje bashdb itp. (Odpowiedź została zmieniona z tymi informacjami)
$ cat test.sh
ARRAY=("hello there" world)for x in $ARRAY;do
echo $x
done
$ shellcheck test.sh
In test.sh line 3:for x in $ARRAY;do^-- SC2128:Expanding an array without an index only gives the first element.
napraw błąd, najpierw spróbuj ...
$ cat test.sh
ARRAY=("hello there" world)for x in ${ARRAY[@]};do
echo $x
done
$ shellcheck test.sh
In test.sh line 3:for x in ${ARRAY[@]};do^-- SC2068:Double quote array expansions, otherwise they're like $* and break on spaces.
Dla powłoki: pobierz plik zip i zaimportuj go do eclipse za pomocą pomocy -> zainstaluj nowe oprogramowanie: archiwum lokalne Dla basheclipse: skopiuj jars do katalogu dropins w eclipse
To jest odpowiedź z pogranicza tylko linków (zobacz także tutaj ). Powinieneś rozszerzyć swoją odpowiedź, tak aby zawierała jak najwięcej informacji, przynajmniej minimum potrzebne do realizacji tego, co sugerujesz, i użyj linków tylko w celach informacyjnych. Zasadniczo posty na Stack Overflow (i wszystkie Stack Exchange) muszą być niezależne. Oznacza to, że odpowiedź musi zawierać wystarczającą ilość informacji, aby czytelnik nie musiał wychodzić z witryny w celu uzyskania wskazówek. W tej chwili tak nie jest w przypadku tej odpowiedzi.
Makyen
jest to pierwsza odpowiedź, jaką znalazłem po przyjrzeniu się wielu, która faktycznie pokazuje, że prawdziwe debugowanie jest możliwe. Standardowe odpowiedzi „set + x” doskonale pasują do samodzielnej odpowiedzi, ale prawie świadomie ignorują prawdziwe pytania dotyczące prawdziwego debugowania. Przyklaskuję tej odpowiedzi 👏
BDB jest obecnie obsługiwane w językach angielskim i hiszpańskim. Aby zmienić język, edytuj plik / etc / default / bdb
abadjm
zrzut ekranu wygląda interesująco, ale nie udało mi się go uruchomić "bdb.sh: wiersz 32: bdbSTR [1]: zmienna niezwiązana"; btw czy pokaże aktualne wartości wszystkich ustawionych zmiennych w każdym kroku, jaki wykonujemy w kodzie?
Aquarius Power
2
set + x = @ECHO OFF, set -x = @ECHO ON.
Możesz dodać -xvopcję do standardowego Shebanga w następujący sposób:
#!/bin/bash -xv
-x: Wyświetla polecenia i ich argumenty w trakcie ich wykonywania. -v: Wyświetla linie wejściowe powłoki w trakcie ich czytania.
ltracejest kolejnym narzędziem Linux podobnym do strace. Jednak ltracezawiera listę wszystkich wywołań biblioteki wywoływanych w pliku wykonywalnym lub działającym procesie. Sama nazwa pochodzi od śledzenia wywołań bibliotecznych. Na przykład:
W poście znajdują się szczegółowe informacje o wprowadzaniu poziomów dziennika, takich jak INFO, DEBUG, ERROR. Śledzenie szczegółów, takich jak wpis skryptu, wyjście skryptu, wejście funkcji, wyjście funkcji.
Odpowiedzi:
Dają ci ślad tego, co jest wykonywane. (Zobacz także „Wyjaśnienie” u dołu odpowiedzi).
Czasami trzeba kontrolować debugowanie w skrypcie. W takim razie, jak przypomniał mi Cheeto , możesz użyć:
To włącza debugowanie. Następnie możesz go ponownie wyłączyć za pomocą:
(Możesz sprawdzić bieżący stan śledzenia, analizując
$-
bieżące flagi dlax
).Ponadto powłoki generalnie udostępniają opcje „
-n
” dla „braku wykonywania” i „-v
” dla trybu „gadatliwego”; możesz użyć ich w połączeniu, aby sprawdzić, czy powłoka uważa, że może wykonać twój skrypt - czasami przydatne, jeśli gdzieś masz niezrównoważony cytat.Istnieje twierdzenie, że
-x
opcja „ ” w Bash różni się od innych powłok (patrz komentarze). Instrukcja Bash mówi:-x
Wydrukuj ślad prostych poleceń,
for
poleceń,case
poleceń,select
poleceń ifor
poleceń arytmetycznych oraz ich argumentów lub powiązanych list słów po ich rozwinięciu i przed wykonaniem. WartośćPS4
zmiennej jest interpretowana, a wynikowa wartość jest wypisywana przed poleceniem i jego rozwiniętymi argumentami.To wcale nie wydaje się wskazywać na inne zachowanie. Nie widzę żadnych innych odnośnych odniesień do „
-x
” w instrukcji. Nie opisuje różnic w kolejności startowej.Wyjaśnienie : W systemach takich jak typowy Linux, gdzie „
/bin/sh
” jest dowiązaniem symbolicznym do „/bin/bash
” (lub gdziekolwiek zostanie znaleziony plik wykonywalny Bash), dwie linie poleceń osiągają równoważny efekt uruchamiania skryptu z włączonym śledzeniem wykonania. W innych systemach (na przykład Solaris i niektóre bardziej nowoczesne warianty Linuksa)/bin/sh
nie jest Bash, a dwie linie poleceń dałyby (nieco) różne wyniki. Przede wszystkim „/bin/sh
” byłby zdezorientowany przez konstrukcje w Bash, których w ogóle nie rozpoznaje. (W Solarisie/bin/sh
jest to powłoka Bourne'a; we współczesnym Linuksie jest to czasami Dash - mniejsza, bardziej ściśle zgodna tylko z POSIX-owa powłoka). Po wywołaniu z taką nazwą, linia „shebang” (#!/bin/bash
„vs'#!/bin/sh
”Podręcznik Bash zawiera sekcję o trybie Bash POSIX, który w przeciwieństwie do długotrwałej, ale błędnej wersji tej odpowiedzi (zobacz również komentarze poniżej), opisuje szczegółowo różnicę między 'Bash wywołany jako
sh
' a 'Bash wywołany jako'bash
”.Podczas debugowania (Bash) skryptu powłoki rozsądne i rozsądne będzie - nawet konieczne - użycie powłoki wymienionej w linii shebang z
-x
opcją. W przeciwnym razie możesz (będzie?) Uzyskać inne zachowanie podczas debugowania niż podczas uruchamiania skryptu.źródło
bash
scenariusz. Uruchomienie skryptu bash w programiesh -x
sprawi, że będzie się on zachowywał zupełnie inaczej! Zaktualizuj swoją odpowiedź.export PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'
Użyłem następujących metod do debugowania mojego skryptu.
set -e
powoduje natychmiastowe zatrzymanie skryptu, jeśli jakikolwiek program zewnętrzny zwróci niezerowy kod zakończenia. Jest to przydatne, jeśli twój skrypt próbuje obsłużyć wszystkie przypadki błędów i gdzie niepowodzenie powinno zostać złapane.set -x
został wspomniany powyżej iz pewnością jest najbardziej użyteczną ze wszystkich metod debugowania.set -n
może być również przydatne, jeśli chcesz sprawdzić skrypt pod kątem błędów składniowych.strace
jest również przydatne, aby zobaczyć, co się dzieje. Szczególnie przydatne, jeśli sam nie napisałeś scenariusza.źródło
strace -f
jest to potrzebne, jeśli chcesz również znaleźć błędy w procesach uruchomionych przez skrypt. (co sprawia, że jest wielokrotnie bardziej rozwlekły, ale nadal przydatny, jeśli ograniczysz go do wywołań systemowych, które Cię interesują).set -e
jest ... kontrowersyjny .Ta odpowiedź jest poprawna i przydatna: https://stackoverflow.com/a/951352
Jednak uważam, że „standardowe” metody debugowania skryptów są nieefektywne, nieintuicyjne i trudne w użyciu. Dla osób przyzwyczajonych do wyrafinowanych debuggerów GUI, które umieszczają wszystko na wyciągnięcie ręki i sprawiają, że praca jest szybka w przypadku łatwych problemów (i możliwych w przypadku trudnych problemów), te rozwiązania nie są zbyt satysfakcjonujące.
Używam kombinacji DDD i bashdb. Pierwsza wykonuje drugą, a druga wykonuje skrypt. Zapewnia to interfejs użytkownika z wieloma oknami z możliwością przechodzenia przez kod w kontekście i przeglądania zmiennych, stosu itp., Bez ciągłego wysiłku umysłowego w celu utrzymania kontekstu w głowie lub ponownego wyświetlania źródła.
Wskazówki, jak to zrobić, znajdziesz tutaj: http://ubuntuforums.org/showthread.php?t=660223
źródło
W skrypcie można również napisać „set -x”.
źródło
Znalazłem narzędzie Shellcheck i może być dla niektórych osób interesujące https://github.com/koalaman/shellcheck
Mały przykład:
napraw błąd, najpierw spróbuj ...
Spróbujmy ponownie...
Znajdź teraz!
To tylko mały przykład.
źródło
Zainstaluj VSCode , a następnie dodaj rozszerzenie debugowania bash i jesteś gotowy do debugowania w trybie wizualnym. zobacz tutaj w akcji.
źródło
Użyj zaćmienia z powłoką wtyczek i basheclipse.
https://sourceforge.net/projects/shelled/?source=directory https://sourceforge.net/projects/basheclipse/?source=directory
Dla powłoki: pobierz plik zip i zaimportuj go do eclipse za pomocą pomocy -> zainstaluj nowe oprogramowanie: archiwum lokalne Dla basheclipse: skopiuj jars do katalogu dropins w eclipse
Postępuj zgodnie z instrukcjami https://sourceforge.net/projects/basheclipse/files/?source=navbar
Napisałem samouczek z wieloma zrzutami ekranu na http://dietrichschroff.blogspot.de/2017/07/bash-eniring-eclipse-for-bash.html
źródło
Zbudowałem debugger Bash. Po prostu daj temu szansę. Mam nadzieję, że pomoże https://sourceforge.net/projects/bashdebugingbash
źródło
Możesz dodać
-xv
opcję do standardowego Shebanga w następujący sposób:-x
: Wyświetla polecenia i ich argumenty w trakcie ich wykonywania.-v
: Wyświetla linie wejściowe powłoki w trakcie ich czytania.ltrace
jest kolejnym narzędziem Linux podobnym dostrace
. Jednakltrace
zawiera listę wszystkich wywołań biblioteki wywoływanych w pliku wykonywalnym lub działającym procesie. Sama nazwa pochodzi od śledzenia wywołań bibliotecznych. Na przykład:Źródło
źródło
Myślę, że możesz wypróbować ten debugger Bash: http://bashdb.sourceforge.net/ .
źródło
Jakaś sztuczka do debugowania grzmotnąć skrypty:
Za pomocą
set -[nvx]
Oprócz
i
za zatrzymanie zrzutu.
Chciałbym mówić o tym,
set -v
który zrzut jest mniejszy niż mniej rozwinięta produkcja.Zrzuć zmienne lub śledzenie w locie
Do testowania niektórych zmiennych używam czasami tego:
za dodanie:
w linii 18. i uruchamiając wynikowy skrypt (z argumentami ), bez konieczności ich edycji.
oczywiście można to wykorzystać do dodania
set [+-][nvx]
:doda
declare -p v1 v2 >&2
po linii 18,set -x
przed linią 22 iset +x
przed linią 26.mała próbka:
Uwaga: Pielęgnacja o
$LINENO
wpłynie on-the-fly modyfikacje!(Aby zobaczyć wynikowy skrypt bez wykonywania, po prostu upuść
bash <(
i) arg1 arg2
)Krok po kroku, czas wykonania
Spójrz na moją odpowiedź dotyczącą profilowania skryptów bash
źródło
Jest dużo szczegółów dotyczących rejestrowania skryptów powłoki za pośrednictwem globalnych zmiennych powłoki. Możemy emulować podobny rodzaj logowania w skrypcie powłoki: http://www.cubicrace.com/2016/03/log-tracing-mechnism-for-shell-scripts.html
W poście znajdują się szczegółowe informacje o wprowadzaniu poziomów dziennika, takich jak INFO, DEBUG, ERROR. Śledzenie szczegółów, takich jak wpis skryptu, wyjście skryptu, wejście funkcji, wyjście funkcji.
Przykładowy dziennik:
źródło