Hoe debug je een bash-script?

Ik “heb problemen met sommige scripts in bash, over fouten en onverwacht gedrag. Ik zou graag de oorzaken van de problemen willen onderzoeken zodat ik kan solliciteren fixes. Is er een manier waarop ik een soort “debug-mode” kan veranderen voor bash, om meer informatie te krijgen?

Answer

Start je bash-script met bash -x ./script.sh of voeg in je script set -x toe om debug-uitvoer te zien.


Aanvullend met bash 4.1 of hoger:

Als je de debug-uitvoer naar een apart bestand wilt schrijven, voeg dit dan toe aan je script:

exec 5> debug_output.txt BASH_XTRACEFD="5" 

Zie: https://stackoverflow.com/a/25593226/3776858


Als je regelnummers wilt zien, voeg dit toe:

PS4="$LINENO: " 


Als je toegang hebt tot logger commando, dan kun je dit gebruiken om debug output te schrijven via je syslog met tijdstempel, scriptnaam en regelnummer:

#!/bin/bash exec 5> >(logger -t $0) BASH_XTRACEFD="5" PS4="$LINENO: " set -x # Place your code here 

U kunt optie -p van logger commando gebruiken om een individuele faciliteit en niveau in te stellen om uitvoer via lokale syslog naar zijn eigen logbestand te schrijven.

Opmerkingen

  • -v kan ook helpen (drukt elke regel af als ze worden uitgevoerd. kan worden gecombineerd met -x). En zie ook: bashdb.sourceforge.net
  • een andere prachtige bron is: shellcheck .net
  • Wat doet ” exec 5 > ” do?
  • @aggsol: als je BASH_XTRACEFD="5" gebruikt, schrijft bash de trace-uitvoer die wordt gegenereerd wanneer set -x is ingeschakeld naar bestandsdescriptor 5. exec 5> >(logger -t $0) leidt uitvoer van bestandsdescriptor 5 om naar logger commando.
  • Ik vraag me af of je het regelnummer en het shellscript-pad of de naam in PS4 kunt krijgen?

Answer

Met set -x

Ik gebruik altijd set -x en set +x. Je kunt gebieden omwikkelen waarvan je wilt zien wat er met hen gebeurt, om de breedsprakigheid omhoog / omlaag te zetten.

#!/bin/bash set -x ..code to debug... set +x 

log4bash

Ook als je “ontwikkelingswerk hebt gedaan en bekend bent met de stijl van loggers met de namen log4j, log4perl, etc., dan wil je misschien gebruik maken van log4bash .

uittreksel

Laten we eerlijk zijn – gewone oude echo snijdt het gewoon niet. log4bash is een poging om betere logboekregistratie voor Bash-scripts te hebben (dwz dat het inloggen in Bash minder waard is).

Van daaruit kunt u dit soort dingen doen in uw Bash-scripts:

#!/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"; 

Resulterend in dit type uitvoer:

        ss1

log4sh

Als je iets meer draagbaars nodig hebt, zijn er ook de oudere log4sh. Werkt vergelijkbaar met log4bash, hier beschikbaar:

Reacties

  • Op Ubuntu heb ik alias say="spd-say" in mijn .bashrc, die de say commando van andere distributies of OS X.
  • set -vx zou een goede combinatie zijn indien gebruikt met trap – trap leesopsporing. Hiermee kun je regel voor regel en zie de resultaten

Antwoord

Er is een bash debugger, bashdb , een installeerbaar pakket op veel distributies. Het gebruikt bashs ingebouwde uitgebreide foutopsporingsmodus (shopt -s extdebug). Het lijkt veel op gdb; hier is een voorbeeldsessie om wat smaak te geven:

$ 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 

Net als in gdb, wordt het statement net voordat het gaat worden uitgevoerd getoond. Dus we kunnen variabelen onderzoeken om te zien wat de instructie zal doen voordat deze het doet.

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 

Dat is niet wat we willen! Laten we eens kijken naar de parameter uitbreiding weer.

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, dat werkt. Laten we newf op de juiste waarde zetten.

bashdb<10> eval newf=${f/%JPG/jpg} $? is 0 bashdb<11> print $f $newf 2ndJPG.JPG 2ndJPG.jpg 

Ziet er goed uit. Ga door met het script.

bashdb<12> next Debugged program terminated normally. Use q to quit or R to restart. $ ls 1st.jpg 2ndJPG.jpg 

Answer

De standaardmethode om scripts te debuggen in de meeste op Bourne gebaseerde shells, zoals bash is om set -x bovenaan je script te schrijven. Dit zal bash meer uitgebreid maken over wat er wordt gedaan / uitgevoerd, en hoe argumenten worden geëvalueerd.

-x Print commands and their arguments as they are executed. 

dit is handig voor zowel de interpreter als inside scripts. Bijvoorbeeld:

$ 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 

In het bovenstaande kunnen we zien waarom find mislukt vanwege enkele enkele aanhalingstekens.

Om de functie te deactiveren, typt u set +x.

Answer

Eclipse gebruiken

U kunt de gecombineerde omgeving van Eclipse en Shelled gebruiken met het “_DEBUG.sh” -script dat hieronder is gelinkt.

Shells wisselen

Door standaard gebruikt het Shelled-ontwikkeltool /bin/dash als de interpreter. Ik heb dit gewijzigd in /bin/bash om een betere compatibiliteit te hebben met de meeste shell-voorbeelden op het web en in mijn omgeving.

OPMERKING: U kunt dit wijzigen door naar: Window -> Voorkeur -> Shell-script -> Tolken

Installatie-instructies

Het Debugger-pakket bevat de stappen voor het gebruik van het _DEBUG.sh -script voor het debuggen van uw script, wat in feite (het readme.txt) is:

  1. Shell-scriptproject maken: Bestand -> Nieuw -> Overig – > Shell-script

-> Shell Script Project Wizard .

  • Maak een Bash-scriptbestand: Bestand -> Nieuw -> bestand . Voor dit voorbeeld is het script.sh. Extensie moet “.sh” zijn en is een must.
  • Kopieer het bestand _DEBUG.sh naar de projectmap.
  • Voeg de volgende tekst naar de top van het bestand script.sh:

    . _DEBUG.sh 
  • Als het bestand is gemaakt in Microsoft Windows, voer dan het File -> Lijnscheidingstekens converteren naar -> Unix .

  • Stel een startconfiguratie voor foutopsporing in: Voer uit -> Foutopsporingsconfiguraties -> Bash-script … Er zijn 2 velden om hier in te stellen:

    a) “Bash script:” – Pad in de werkruimte van Eclipse naar het Bash-script om te debuggen.
    e) “Debugger port:” 33333

  • Schakel over naar het Debug-perspectief. Start de foutopsporingssessie. Start script.sh vanuit bash shell.

  • De bash debug UI

    voer de beschrijving van de afbeelding hier in

    Deze bash-debugger heeft de volledige kenmerken van standaard programmeer-debuggers zoals:

    • Schakelen tussen breekpunten
    • Enkele stapsgewijze bediening
    • Step-in, Step-out, Step-over-functies en subroutines
    • Code of variabelen onderzoeken op elk moment terwijl het script wordt uitgevoerd

    De Shelled (Shell Script Editor) IDE (Integrated Development Environment) heeft een toegevoegde bonus door het uitvoeren van contextcontrole, markeren en inspringen tijdens het schrijven van je script. Als het niet correct inspringt, kun je daar mogelijk onmiddellijk veel fouten markeren / lokaal plaatsen.

    Dan zijn er andere IDE-voordelen zoals:

    • TODO-takenlijst
    • Mylyn-taak
    • Bladwijzerlijst
    • Meerdere Window Editing
    • Remote Sharing van de omgeving

    Reacties

    • Coole tip. Leuk om te weten dat Bash worden op deze manier opgespoord.

    Answer

    Er is de afgelopen jaren een prachtige bron verschenen: http://shellcheck.net

    het laat je meer zien dan de gewone bash, waardoor je gemakkelijk die vervelende niet-gesloten aanhalingstekens of gekrulde haakjes, enz.

    Zorg ervoor dat u geen gevoelige informatie (ips, wachtwoorden, enz.) over het net plakt … (vooral omdat het http is, niet-versleuteld) (ik geloof dat shellcheck ook beschikbaar is om te downloaden, maar ik weet het niet zeker)

    Antwoord

    Tegenwoordig is er de VS Code Bash Debug.

    https://marketplace.visualstudio.com/items?itemName=rogalmic.bash-debug

    Het heeft “Step in / out / over “en toont ook de waarde van elke variabele.

    Schermafbeelding VS Code Bash Debug

    Opmerkingen

    • dit antwoord behandelt de vraag niet in de juiste context; uitgaande van de opdrachtregel aangezien IDE niet werd genoemd

    Antwoord

    gebruik gewoon:

    #!/bin/bash -x 

    hetzelfde voor shell:

    #!/bin/sh -x 

    Geef een reactie

    Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *