Mam problemy z niektórymi skryptami w bashu, błędami i nieoczekiwanymi zachowaniami. Chciałbym zbadać przyczyny problemów, aby móc złożyć wniosek poprawki. Czy istnieje sposób, w jaki mogę włączyć jakiś „tryb debugowania” basha, aby uzyskać więcej informacji?
Odpowiedź
Uruchom swój skrypt bash za pomocą bash -x ./script.sh
lub dodaj w swoim skrypcie set -x
, aby zobaczyć wyniki debugowania.
Dodatkowo z bash
4.1 lub nowszym:
Jeśli chcesz zapisać wyniki debugowania w oddzielnym pliku, dodaj to do swojego skryptu:
exec 5> debug_output.txt BASH_XTRACEFD="5"
Zobacz: https://stackoverflow.com/a/25593226/3776858
Jeśli chcesz zobaczyć numery linii, dodaj to:
PS4="$LINENO: "
Jeśli masz dostęp do logger
, możesz użyć tego polecenia do zapisania wyników debugowania za pośrednictwem swojego syslog z sygnaturą czasową, nazwą skryptu i numerem linii:
#!/bin/bash exec 5> >(logger -t $0) BASH_XTRACEFD="5" PS4="$LINENO: " set -x # Place your code here
Możesz użyć opcji -p
polecenia logger
, aby ustawić indywidualny obiekt i poziom zapisywać dane wyjściowe przez lokalny syslog do własnego pliku dziennika.
Komentarze
Odpowiedź
Używając set -x
Zawsze używam set -x
i set +x
. Możesz zawijać obszary, które chcesz zobaczyć, co się z nimi dzieje, aby zwiększyć lub zmniejszyć szczegółowość.
#!/bin/bash set -x ..code to debug... set +x
log4bash
Ponadto jeśli wykonałeś już prace programistyczne i znasz styl rejestratorów o nazwach log4j, log4perl itd., możesz użyć log4bash .
fragment
Spójrz prawdzie w oczy – zwykłe stare echo po prostu go nie wycina. log4bash to próba lepszego rejestrowania skryptów Bash (tj. sprawienie, aby logowanie w Bash było do niczego).
Stamtąd możesz robić takie rzeczy w swoim Skrypty Bash:
#!/usr/bin/env bash source log4bash.sh log "This is regular log message... log and log_info do the same thing"; log_warning "Luke ... you turned off your targeting computer"; log_info "I have you now!"; log_success "You"re all clear kid, now let"s blow this thing and go home."; log_error "One thing"s for sure, we"re all gonna be a lot thinner."; # If you have figlet installed -- you"ll see some big letters on the screen! log_captains "What was in the captain"s toilet?"; # If you have the "say" command (e.g. on a Mac) log_speak "Resistance is futile";
Wynik tego typu danych wyjściowych:
log4sh
Jeśli potrzebujesz czegoś bardziej przenośnego, jest też starszy log4sh
. Działa podobnie do log4bash
, dostępny tutaj:
Komentarze
- W Ubuntu mam
alias say="spd-say"
w moim .bashrc, co imitujesay
z innych dystrybucji lub OS X. - set -vx będzie dobrym połączeniem, jeśli zostanie użyte z debugowaniem odczytu trap – trap. Pozwala to przechodzić wiersz po wierszu i zobacz wyniki
Odpowiedź
Dostępny jest debugger bash, bashdb , który jest pakietem do zainstalowania w wielu dystrybucjach. Używa wbudowanego rozszerzonego trybu debugowania basha (shopt -s extdebug
). Wygląda bardzo podobnie do gdb; tutaj jest przykładowa sesja, aby nadać trochę smaku:
$ ls 1st.JPG 2ndJPG.JPG $ cat ../foo.sh for f in *.JPG do newf=${f/JPG/jpg} mv $f $newf done $ bashdb ../foo.sh (foo.sh:1): 1: for f in *.JPG bashdb<0> next (foo.sh:3): 3: newf=${f/JPG/jpg} bashdb<1> next (foo.sh:4): 4: mv $f $newf
Podobnie jak w gdb, instrukcja jest wyświetlana tuż przed wykonaniem. Możemy więc sprawdzić zmienne, aby zobaczyć, co zrobi instrukcja, zanim to zrobi.
bashdb<2> print $f $newf 1st.JPG 1st.jpg bashdb<3> next (foo.sh:1): 1: for f in *.JPG bashdb<4> next (foo.sh:3): 3: newf=${f/JPG/jpg} bashdb<5> next (foo.sh:4): 4: mv $f $newf bashdb<6> print $f $newf 2ndJPG.JPG 2ndjpg.JPG
Nie tego chcemy! Spójrzmy na ponownie rozwijanie parametrów.
bashdb<7> print $f ${f/JPG/jpg} 2ndJPG.JPG 2ndjpg.JPG bashdb<8> print $f ${f/JPG$/jpg} 2ndJPG.JPG 2ndJPG.JPG bashdb<9> print $f ${f/%JPG/jpg} 2ndJPG.JPG 2ndJPG.jpg
OK, to działa. Ustaw „s ustaw newf
na poprawną wartość.
bashdb<10> eval newf=${f/%JPG/jpg} $? is 0 bashdb<11> print $f $newf 2ndJPG.JPG 2ndJPG.jpg
Wygląda dobrze. Kontynuuj skrypt.
bashdb<12> next Debugged program terminated normally. Use q to quit or R to restart. $ ls 1st.jpg 2ndJPG.jpg
Odpowiedź
Standardowa metoda debugowania skryptów w większości powłok opartych na Bourne, na przykład bash ma napisać set -x
na początku skryptu. Dzięki temu bash będzie bardziej szczegółowy na temat tego, co jest robione / wykonywane i jak są oceniane argumenty.
-x Print commands and their arguments as they are executed.
jest to przydatne w przypadku interpretera lub wewnątrz skryptów. Na przykład:
$ find "$fileloc" -type f -prune "$filename" -print + find /var/adm/logs/morelogs -type f -prune "-name *.user" -print find: unknown predicate "-name *.user" $ find "$fileloc" -type f -prune $filename -print + find /var/adm/logs/morelogs -type f -prune -name "*.user" -print find: "/var/adm/logs/morelogs": No such file or directory
Powyżej możemy zobaczyć, dlaczego find nie działa z powodu kilku pojedynczych cudzysłowów.
Aby dezaktywować tę funkcję, po prostu wpisz set +x
.
Odpowiedz
Korzystanie z Eclipse
Możesz używać połączonego środowiska Eclipse i Shelled ze skryptem „_DEBUG.sh”, do którego link znajduje się poniżej.
- Wtyczka Eclipse Shelled:
http://sourceforge.net/projects/shelled/files/shelled/update/ - debugger bash – działa tylko z powłoką:
http://sourceforge.net/projects/basheclipse/
Przełączanie powłok
Przez domyślnie narzędzie programistyczne Shelled używa /bin/dash
jako interpretera. Zmieniłem to na /bin/bash
, aby uzyskać lepszą zgodność z większością przykładów powłoki w Internecie i moim środowisku.
UWAGA: Możesz to zmienić, przechodząc do: Window -> Preferencje -> Skrypt powłoki -> Tłumacze ustni
Instrukcje konfiguracji
Pakiet Debugger zawiera instrukcje korzystania ze skryptu _DEBUG.sh
do debugowania skryptu, którym jest zasadniczo (plik readme.txt):
- Utwórz projekt skryptu powłoki: Plik -> Nowy -> Inne – > Skrypt powłoki
-> Kreator projektu skryptu powłoki .
script.sh
. Rozszerzenie powinno mieć „.sh” i jest konieczne. _DEBUG.sh
do folderu projektu. Wstaw następujący tekst na początek pliku script.sh
:
. _DEBUG.sh
Jeśli plik jest tworzony w systemie Microsoft Windows, a następnie wykonaj Plik -> Konwertuj ograniczniki linii na -> Unix .
Skonfiguruj konfigurację uruchamiania debugowania: Uruchom -> Konfiguracje debugowania -> Skrypt Bash … W tym miejscu należy ustawić 2 pola:
a) „Skrypt Bash:” – Ścieżka w obszarze roboczym Eclipse do skryptu Bash do debugowania.
e) „Port debugera:” 33333
Przełącz do perspektywy debugowania. Rozpocznij sesję debugowania. Uruchom script.sh
z powłoki bash.
Interfejs debugowania bash
Ten debugger bash ma wszystkie funkcje standardowych debuggerów programowania, takie jak:
- Przełączanie punktu przerwania
- Pojedyncza operacja krok po kroku
- Funkcje Step-in, Step-out, Step-over i podprogramy
- Badanie kodu lub zmiennych w dowolnym momencie działania skryptu
Shelled (edytor skryptów powłoki) IDE (zintegrowane środowisko programistyczne) ma dodatkową zaletę sprawdzania kontekstu, podświetlania i wcięć podczas pisania skryptu. Jeśli wcięcie nie jest poprawne, możesz od razu zgłosić wiele błędów w tym miejscu.
Istnieją inne zalety środowiska IDE , na przykład:
- Lista zadań TODO
- Zadanie Mylyn
- Lista zakładek
- Wiele Edycja okien
- Zdalne udostępnianie środowiska
Komentarze
- Fajna wskazówka. Miło wiedzieć, że Bash może być debugowanym w ten sposób.
Odpowiedź
W ostatnich latach pojawił się wspaniały zasób: http://shellcheck.net
Pokazuje więcej niż zwykły bash, pozwalając łatwo znaleźć te nieznośne niezamknięte cudzysłowy lub kręcone nawiasy, itp.
Tylko upewnij się, że nie wklejasz wrażliwych informacji (ips, haseł, itp.) przez sieć … (zwłaszcza że jest to http, niezaszyfrowane) (wierzę, że shellcheck jest również dostępny pobrać, ale nie jestem pewien)
Odpowiedź
Obecnie istnieje debugowanie VS Code Bash.
https://marketplace.visualstudio.com/items?itemName=rogalmic.bash-debug
Ma opcję „Wejdź / wyjdź / over ”, a także pokazuje wartość każdej zmiennej.
Komentarze
- ta odpowiedź nie odnosi się do pytania we właściwym kontekście; zakładając wiersz poleceń, ponieważ nie wspomniano o IDE
Odpowiedź
po prostu użyj:
#!/bin/bash -x
to samo dla powłoki:
#!/bin/sh -x
BASH_XTRACEFD="5"
, bash zapisuje dane wyjściowe śledzenia generowane, gdyset -x
jest włączona deskryptor pliku 5.exec 5> >(logger -t $0)
przekierowuje dane wyjściowe z deskryptora pliku 5 dologger
polecenie.