Voer meerdere opdrachten achter elkaar uit in een bash-script en faal als ten minste één ervan faalt

Ik heb een bash-script dat ik gebruik om meerdere opdrachten achter elkaar uit te voeren en ik moet een afsluitcode die niet nul is retourneren als ten minste één opdracht in de reeks een afsluitcode die niet nul is retourneert. Ik weet dat daar een waitcommando voor is, maar ik weet niet zeker of ik begrijp hoe ik het moet gebruiken.

UPDHet script ziet er als volgt uit:

#!/bin/bash
command1
command2
command3

Alle opdrachten worden op de voorgrond uitgevoerd. Alle opdrachten moeten worden uitgevoerd, ongeacht de afsluitstatus die de vorige opdracht heeft geretourneerd (het mag zich dus niet gedragen als “afsluiten bij eerste fout”). In principe moet ik alle exit-statussen verzamelen en dienovereenkomstig de globale exit-status retourneren.


Antwoord 1, autoriteit 100%

Doe het gewoon:

EXIT_STATUS=0
command1 || EXIT_STATUS=$?
command2 || EXIT_STATUS=$?
command3 || EXIT_STATUS=$?
exit $EXIT_STATUS

Weet niet zeker welke van de statussen het moet retourneren als meerdere opdrachten zijn mislukt.


Antwoord 2, autoriteit 18%

Als je met sequentie pipe bedoelt, dan moet je pipefailin je script instellen zoals set -o pipefail. Van man bash:

De retourstatus van een pijplijn is de uitgangsstatus van de laatste opdracht,
tenzij de pipefail-optie is
ingeschakeld. Als pijpfout is ingeschakeld, is de retourstatus van de pijplijn de waarde van de laatste (meest rechtse)
opdracht om af te sluiten met een status die niet nul is, of nul als alle opdrachten met succes worden afgesloten. Als de gereserveerde
woord ! aan een pijpleiding voorafgaat, is de uitgangsstatus van die pijplijn de logische ontkenning van de uitgang
staat zoals hierboven beschreven. De shell wacht totdat alle opdrachten in de pijplijn zijn beëindigd voordat
een waarde retourneren.

Als je alleen opeenvolgende commando’s bedoelt, controleer dan gewoon de exit-status van elke commando en stel een vlag in als de exit-status geen nul is. Laat uw script de waarde van de vlag retourneren zoals:

#!/bin/bash
EXIT=0
grep -q A <<< 'ABC' || EXIT=$?  # Will exit with 0
grep -q a <<< 'ABC' || EXIT=$?  # Will exit with 1
grep -q A <<< 'ABC' || EXIT=$?  # Will exit with 0
echo $EXIT                      # Will print 1
exit $EXIT                      # Exit status of script will be 1 

Dit gebruikt de logische operator OR ||om alleen EXITin te stellen als de opdracht mislukt. Als meerdere opdrachten mislukken, wordt de exit-status van de laatste mislukte opdracht door het script geretourneerd.

Als deze commando’s niet op de achtergrond draaien, is waithier niet relevant.


Antwoord 3, autoriteit 5%

Als je wilt weten welk commando is mislukt, maar niet noodzakelijk de retourcode, dan kun je het volgende gebruiken:

#!/bin/bash
rc=0;
counter=0;
command1 || let "rc += 1 << $counter"; let counter+=1;
command2 || let "rc += 1 << $counter"; let counter+=1;
command3 || let "rc += 1 << $counter"; let counter+=1;
exit $rc

Dit gebruikt bitverschuiving in bash om de bit in te stellen die overeenkomt met welk commando is mislukt.

Als de eerste opdracht is mislukt, krijgt u dus een retourcode van 1 (=2^0), als de derde mislukt, krijgt u een retourcode van 8 (=2^3), en als zowel de eerste als de het derde commando mislukte, je zou 9 krijgen als de retourcode.


Antwoord 4

Als je wilt weten welke opdracht is mislukt:

#!/bin/bash
EXITCODE_RESULT=0
command1
EXIT_CODE_1=$?
command2
EXIT_CODE_2=$?
command3
EXIT_CODE_3=$?
for i in ${!EXIT_CODE_*}
do
    # check if the values of the EXIT_CODE vars contain 1
    EXITCODE_RESULT=$(($EXITCODE_RESULT || ${!i}))
    if [ ${!i} -ne 0 ]
    then
        var_fail+="'$i' "
    else
        var_succ+="'$i' "
    fi
done

In $var_fail krijg je een lijst van de mislukte EXIT_CODE vars en in $var_succ een lijst van de succesvolle

Other episodes