Jak debugować skrypt bash?

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

  • -v również może pomóc (wypisuje każdą linię w trakcie wykonywania. można łączyć z -x). Zobacz także: bashdb.sourceforge.net
  • innym wspaniałym źródłem jest: shellcheck .net
  • Co robi ” exec 5 > ” zrobić?
  • @aggsol: Jeśli używasz BASH_XTRACEFD="5", bash zapisuje dane wyjściowe śledzenia generowane, gdy set -x jest włączona deskryptor pliku 5. exec 5> >(logger -t $0) przekierowuje dane wyjściowe z deskryptora pliku 5 do logger polecenie.
  • Zastanawiasz się, czy możesz uzyskać numer linii i ścieżkę skryptu powłoki lub nazwę na PS4?

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:

        ss1

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 imituje say 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.

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):

  1. Utwórz projekt skryptu powłoki: Plik -> Nowy -> Inne – > Skrypt powłoki

-> Kreator projektu skryptu powłoki .

  • Utwórz plik skryptu Bash: Plik -> Nowy -> Plik . W tym przykładzie będzie to script.sh. Rozszerzenie powinno mieć „.sh” i jest konieczne.
  • Skopiuj plik _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

    tutaj wprowadź opis obrazu

    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.

    Zrzut ekranu debugowania VS Code Bash

    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 

    Dodaj komentarz

    Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *