Jak debugować skrypt bash?

31

Czy jest jakiś sposób na debugowanie skryptu bash bez użycia echa i logowania?

Mówię o używaniu punktów przerwania i tym podobnych.

UAdapter
źródło

Odpowiedzi:

20

Istnieje kilka różnych sposobów, tj .:

  • Uruchom skrypt z opcją -x

    bash -x yourscript.sh
  • Dodaj set -xnowy wiersz na początku pliku #!/bin/bashskryptu po Shebang, a przed początkiem skryptu set -vwyświetli wiersze wejściowe powłoki, set -xwyświetli wykonane polecenia i argumenty

  • zamień shebang pliku skryptu na #!/bin/bash -xv

NES
źródło
4

Możesz użyć tej małej funkcji, aby przejść do „konsoli”:

function debug
{
    echo "#############|  Entering DEBUG mode  |####################";
    cmd=""
    while [[ $cmd != "exit" ]]; do
        read -p "> " cmd
        case "$cmd" in
            vars ) ( set -o posix ; set );;
            exit ) ;;
            * ) eval "$cmd";;
        esac
    done
    echo "#############|  End of DEBUG mode |####################";
}

Następnie w skrypcie (PRZYKŁAD):

for file in *; do
...
   if [[ $file == "strange_case.txt" ]]; then
       # break the code here to analyze:
       debug
   fi
...
done

Przyjmie każde polecenie, zachowując zmienne lokalne. Aby wyjść z trybu „debugowania”, wpisz „exit” (nie wyjdzie ze skryptu) i będzie kontynuował kod. Jeśli użyjesz „debugowania” w pętli, zatrzyma się za każdym razem. Możesz owinąć go „if” (jak w powyższym przykładzie) lub utworzyć funkcję „watch”:

function debug_watch
{
    if [[ $1 == $2 ]]; then
        debug
    fi
}

# And Use it:

debug_watch "$file" "strange_case.txt"

Dodałem także polecenie „vars”, które zrzuci wszystkie dostępne zmienne i ich wartości. Możesz także dodawać własne spersonalizowane polecenia.

Zrobiłem kod w kilka minut, więc używaj go na własne ryzyko. Należy pamiętać, że w trybie debugowania można wykonać dowolne polecenie, dlatego może ono stanowić zagrożenie dla bezpieczeństwa, jeśli zostanie pozostawione w skrypcie produkcyjnym.

lepe
źródło
3
Unikaj używania nazw zmiennych pisanych wielkimi literami. Ryzyko nadpisania specjalnych zmiennych powłoki i zmiennych środowiskowych. Upewnij się również, że zacytowałeś rozszerzenia parametrów, gdy są one używane jako argumenty, aby uniknąć podziału słów i rozwijania nazw ścieżek w wyniku. np . * ) eval "$cmd" ;;i debug_watch "$file" strange_case.txt.
geirha
Edytowano kod zgodnie z sugestią geirha.
Lepe
2

Zgodnie z tym, co mówi NES, w bash ustawiono flagi umożliwiające debugowanie.

set -xFlaga może być ustawione i wyłączenie zarówno z terminala lub z poziomu skryptu. Za pomocą +lub -:

#!/bin/bash
#fileinfo
ls -l $1
set -x      # start debugging here
wc -l $1
set +x      # stop debugging here
file $1
set -v      # start verbose output
w | more    
echo ""
echo -n "Number of users: "
set +v      # end verbose output
who | wc -l

Oto, co setrobią polecenia:

  • set -f Wyłącz generowanie nazw plików przy użyciu metaznaków.
  • set -v Wyświetla (pełne) wiersze wprowadzania powłoki podczas ich odczytywania.
  • set -x Wydrukuj ślady poleceń przed wykonaniem polecenia.

setfaktycznie ma wiele funkcji, ale żałuję, że nie ma strony podręcznika, ponieważ jest to narzędzie wbudowane w powłokę. Podręcznik do zestawu znajduje się w dokumentacji GNU Bash .

Istnieje wiele narzędzi wiersza poleceń, które mogą pomóc uzyskać szczegółowe informacje o programie, takie jak:

  • stat wyświetlać status pliku lub systemu plików
  • file określić typ pliku.
  • hexdump filtr wyświetlający określone pliki w różnych formatach
  • nohup Uruchom skrypt, który się nie zawiesi

    i wiele innych. Próbowałem wymyślić polecenie, które pokazuje ukryte postacie, ale nie mogę tego teraz zrobić. Hexdump to zrobi, ale jest lepszy.

Polecenie klawisza ctrl\spowoduje zrzut pamięci uruchomionego programu lub skryptu. Następnie możesz przeanalizować rdzeń rdzeniowy. Prawdopodobnie użyłbym gdb do analizy zrzutu rdzeniowego, ale istnieje wiele programów do tego.

Powłoka bash ma również kilka fajnych opcji debugowania. opcje --debugger, -vpełne --dump-stringsi inne przydatne opcje, aby ci pomóc. Sprawdź je za pomocą man bash.

trapPoleceń (shell wbudowane) może być bardzo pomocne dla Ciebie. trap mówi, że jeśli twój program nieoczekiwanie zakończy działanie, wykonaj coś. Można przeczytać o pułapki i inne poręczne builtins Bash Shell tutaj .

Mówiąc ogólnie, debugowanie jest ogromnym tematem w dowolnym języku. Niektóre inne tematy, które mogą być przydatne do debugowania w dowolnym języku programowania, to przekierowanie powłoki i przetwarzanie sygnału.

Wreszcie zdaję sobie sprawę, że przykład, którego użyłem, jest trywialny, ale niektóre skrypty powłoki mogą mieć setki linii. W takich sytuacjach lubię wstawiać tagi komentarzy i blokować kod, który podejrzewam, że jest wadliwy, lub alternatywnie, wstawić polecenie wyjścia i próbować izolować kod funkcjonalny od uszkodzonego kodu, stosując technikę dzielenia i podbijania.

j0h
źródło
1

Opcją GUI do debugowania skryptu bash jest Eclipse IDE z wtyczkami BashEclipse / Shelled.

Daje to funkcje twojego pytania ( breakpoints and stuff) wraz z wieloma innymi funkcjami do debugowania złożonych skryptów bash.

Niektóre funkcje obejmują:
( https://unix.stackexchange.com/questions/155551/how-to-debug-a-bash-script )

  • Przełącznik punktu przerwania
  • Pojedyncza operacja krok po kroku
  • Funkcje i podprogramy Step-in, Step-out, Step-over
  • Badanie zmiennych kodu w dowolnym momencie podczas działania skryptu
  • Lista zadań do zrobienia
  • Lista zakładek
  • Edycja wielu okien
  • Zdalne udostępnianie środowiska projektu

Perspektywa edytora skryptów: Eclipse Script IDE

Perspektywa debugowania: Perspektywa debugowania skryptu Eclipse

Kroki użycia to dodanie Shelledi BashEclipsewtyczek do zaćmienia. Następnie uruchom procedurę podaną w pliku tekstowym BashEclipse read me, aby uruchomić debugger.

LD James
źródło