Hvordan afslutter man et shell-script, hvis en del af det fejler?

Hvordan kan jeg skrive et shell-script, der afsluttes, hvis en del af det fejler? For eksempel, hvis følgende kodestykke fejler, skal scriptet afslutte.

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

Svar

En tilgang ville være at tilføje set -e til begyndelsen af dit script. Det betyder (fra help set):

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

Så hvis nogen af dine kommandoer mislykkes, afslutter scriptet.

Alternativt kan du tilføje eksplicit exit udsagn ved de mulige fejlpunkter:

command || exit 1 

Kommentarer

  • I (og bash wiki ) vil hellere folk lægge nogle tanker i korrekt fejlhåndtering i stedet for at bruge funktionen (brudt efter design IMO) set -e. Det gælder dog ikke '. OPen ønsker at afslutte scriptet efter 5 mislykkede forsøg på at køre kommandoen.
  • @St é phaneChazelas I won ' t skændes med dig om, at det ' er brudt, jeg ' er sikker på at du ' har ret. OP spurgte dog " Hvordan kan jeg skrive et shell-script, der udgår, hvis en del af det fejler? ", hvad gør dig tror det ' handler om at afslutte efter 5 fejl?
  • fordi jeg ikke kan ' ikke tænke på nogen anden måde spørgsmål kan fortolkes.
  • @St é phaneChazelas du kan godt have ret. Jeg fortolkede det bogstaveligt: hvordan kan hele scriptet afslutte, hvis nogen del af det fejler. Og set -e er den eneste måde, jeg ved det på.
  • I det script-snipet er de kommandoer, der kunne udløse set -e er sleep (break at være en speciel indbygget ville få scriptet til at afslutte ved fejl i de fleste skaller, kommandoer i if eller til venstre for && påvirkes ikke af set -e, n=... kunne mislykkes, hvis n er skrivebeskyttet, men så ville det også afslutte scriptet uden set -e, så fortolkning lyder ret usandsynligt. Jeg er enig i, at spørgsmålet er dårligt formuleret.

Svar

Du kan afslutte et script hvor som helst ved hjælp af nøgleordet exit. Du kan også angive en udgangskode for at angive for andre programmer, at eller hvordan dit script mislykkedes, f.eks. exit 1 eller exit 2 osv. (Af konvention er exit kode 0 for succes, og alt større end 0 betyder fiasko, dog også ved konvention , udgangskoder over 127 er reserveret til unormal afslutning (f.eks. ved et signal)).

Den generiske konstruktion til afslutning ved fejl er

if [ failure condition ]; then exit n fi 

med passende failure condition og n. Men i specifikke scenarier kan du gå anderledes ud. Nu for din sag fortolker jeg dit spørgsmål om, at hvis nogen af de fem påkaldelser af gksu mislykkes, så mener du at afslutte. En måde er at bruge en funktion 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 derefter påkalde sløjfen ved at try_command.

Der er (mere) avancerede eller sofistikerede måder at behandle dit spørgsmål på. Ovenstående løsning er dog mere tilgængelig for begyndere end, 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 afslutter scriptet, medmindre det kaldes i en subshell. Hvis den del af scriptet er i en subshell, for eksempel fordi den “er inden for (...) eller $(...) eller en del af en rørledning , så afslutter det kun den subshell .

I så fald, hvis du vil have scriptet ud foruden subshell, så ” Jeg skal ringe til exit når denne subshell afsluttes.

For eksempel her med 2 indlejrede niveauer af 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 blive vanskeligere, hvis subshell er en del af en pipeline. bash har et specielt $PIPESTATUS array svarende til zsh “s $pipestatus en der kan hjælpe dig 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 udfører en handling efter modtagelse af 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 

Kør dette og lad det afslutte normalt. Det fælder på signal 0.

EXIT 

Kør det igen og afbryd med ^ C. Det fælder både signal 2 og signal 0.

CTL-C EXIT 

En udgangsstatus, der ikke er nul, fanges 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 $? )& 

Skriv et svar

Din e-mailadresse vil ikke blive publiceret. Krævede felter er markeret med *