Hvordan avslutte et skallskript hvis en del av det mislykkes?

Hvordan kan jeg skrive et skallskript som går ut, hvis en del av det mislykkes? Hvis for eksempel kodebiten mislykkes, skal skriptet avsluttes.

n=0 until [ $n -ge 5 ] do gksu *command* && break n=$[$n+1] sleep 3 

Svar

En tilnærming ville være å legge til set -e i begynnelsen av skriptet. Det betyr (fra help set):

 -e Exit immediately if a command exits with a non-zero status. 

Så hvis noen av kommandoene dine mislykkes, avsluttes skriptet.

Alternativt kan du legge til eksplisitte exit utsagn ved mulige feilpunkter:

command || exit 1 

Kommentarer

  • I (og bash wiki ) vil heller at folk legger noen tanker i riktig feilhåndtering i stedet for å bruke funksjonen (ødelagt av design IMO) set -e. Det gjelder ikke ' her. OP-en vil avslutte skriptet etter 5 mislykkede forsøk på å kjøre kommandoen.
  • @St é phaneChazelas jeg vant ' t krangle med deg om det ' er ødelagt, jeg ' er sikker på at du ' har rett. OP spurte imidlertid " Hvordan kan jeg skrive et skallskript som går ut, hvis en del av det mislykkes? ", hva gjør deg tror det ' handler om å avslutte etter 5 feil?
  • fordi jeg ikke kan ' ikke tenke på noen annen måte spørsmålet kan tolkes.
  • @St é phaneChazelas du kan godt ha rett. Jeg tolket det bokstavelig: hvordan kan hele skriptet gå ut hvis noen del av det mislykkes. Og set -e er den eneste måten jeg vet å gjøre det.
  • I skriptnippelen er kommandoene som kan utløse set -e er sleep (break å være en spesiell innebygd ville føre til at skriptet avsluttes ved feil i de fleste skjell, kommandoer i if eller til venstre for && påvirkes ikke av set -e, n=... kan mislykkes hvis n er skrivebeskyttet, men da vil det også gå ut av skriptet uten set -e), slik at tolkning høres ganske usannsynlig ut. Jeg er enig i at spørsmålet er dårlig formulert.

Svar

Du kan avslutte et skript hvor som helst ved hjelp av nøkkelordet exit. Du kan også spesifisere en utgangskode for å indikere for andre programmer at eller hvordan skriptet ditt mislyktes, f.eks. exit 1 eller exit 2 osv. (Etter konvensjon er utgangskode 0 for suksess og alt større enn 0 betyr feil, men også etter konvensjon , er utgangskoder over 127 reservert for unormal avslutning (f.eks. av et signal)).

Den generiske konstruksjonen for å avslutte ved feil er

if [ failure condition ]; then exit n fi 

med passende failure condition og n. Men i spesifikke scenarier kan du gå annerledes. Nå for din sak tolker jeg spørsmålet ditt om at hvis noen av de fem anropene til gksu mislykkes, så mener du å avslutte. En måte er å bruke en funksjon som denne

function try_command { for i in 1 2 3 4 5 ; do if gksu command ; then return 0 fi fi exit 1 } 

og deretter påkalle sløyfen ved å try_command.

Det er (mer) avanserte eller sofistikerte måter å håndtere spørsmålet ditt på. Løsningen ovenfor er imidlertid mer tilgjengelig for nybegynnere enn for eksempel Stephanes løsning.

Svar

attempt=0 until gksu command; do attempt=$((attempt + 1)) if [ "$attempt" -gt 5 ]; then exit 1 fi done 

exit avslutter skriptet med mindre det kalles i en subshell. Hvis den delen av skriptet er i en subshell, for eksempel fordi den ligger innenfor (...) eller $(...) eller en del av en rørledning , så vil den bare avslutte den underskallen .

I så fall, hvis du vil at skriptet skal avsluttes i tillegg til underskallet, så Jeg må ringe exit når det subshell avsluttes.

For eksempel, her med to nestede nivåer av subshells:

( life=hard output=$( echo blah [ "$life" = easy ] || exit 1 # exit subshell echo blih not run ) || exit # if the subshell exits with a non-zero exit status, # exit as well with the same exit status echo not run either ) || exit # if the subshell exits with a non-zero exit status, # exit as well with the same exit status 

Det kan bli vanskeligere hvis subshell er en del av en rørledning. bash har en spesiell $PIPESTATUS matrise, som zsh «s $pipestatus en som kan hjelpe deg her:

{ echo foo exit 1 echo bar } | wc -c subshell_ret=${PIPESTATUS[0]} if [ "$subshell_ret" -ne 0 ]; then exit "$subshell_ret" fi 

Svar

Trap vil utføre en handling etter mottak av et signal.

trap "echo EXIT; exit" 0 trap "echo HUP; exit" 1 trap "echo CTL-C; exit" 2 trap "echo QUIT; exit" 3 trap "echo ERR; exit" ERR n=0 until [ $n -ge 5 ] do n=$[$n+1] echo $n sleep 3 done 

Kjør dette og la det gå normalt. Det feller på signal 0.

EXIT 

Kjør den igjen og avbryt med ^ C. Den feller både signal 2 og signal 0.

CTL-C EXIT 

En utgangsstatus som ikke er null, blir fanget i ERR

ERR EXIT 

Svar

pass_to_functio() { echo "command exited with status $1" } ( exec <Any Command > & child_pid=$! wait $child_pid pass_to_function $? )& 

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert. Obligatoriske felt er merket med *