Kuinka poistutaan komentosarjakomentosarjasta, jos yksi osa epäonnistuu?

Kuinka voin kirjoittaa komentosarjan, joka poistuu, jos yksi sen osa epäonnistuu? Esimerkiksi, jos seuraava koodinpätkä epäonnistuu, komentosarjan pitäisi poistua.

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

Vastaa

Yksi tapa olisi lisätä set -e komentosarjan alkuun. Tämä tarkoittaa (mistä: help set):

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

Joten jos jokin komennoista epäonnistuu, komentosarja poistuu.

Vaihtoehtoisesti voit lisätä eksplisiittisiä exit -lausekkeita mahdollisiin vikapisteisiin:

command || exit 1 

Kommentit

  • Minä (ja bash-wiki ) mieluummin ihmiset ajattelevat asianmukaista virheiden käsittelyä pikemminkin kuin (muotoilun mukaan IMO) set -e -ominaisuutta. Se ei kuitenkaan ' sovellu tähän. OP haluaa lopettaa komentosarjan viiden epäonnistuneen komennon suorittamisen jälkeen.
  • @St é phaneChazelas I won ' t kiistä kanssasi siitä, onko se ' rikkoutunut, olen ' varma, että olet ' uudelleen oikeassa. OP kysyi kuitenkin " miten voin kirjoittaa komentosarjan, joka poistuu, jos yksi osa epäonnistuu? ", mikä saa sinut ajatteletko ' s poistumista viiden epäonnistumisen jälkeen?
  • koska en voi ' ajatella muuta tapaa kysymys voidaan tulkita.
  • @St é phaneChazelas, saatat olla oikeassa. Tulkitsin sen kirjaimellisesti: kuinka koko komentosarja voi poistua, jos jokin sen osa epäonnistuu. Ja set -e on ainoa tapa, jolla tiedän sen tekevän.
  • Koodikoodinpätkässä komennot, jotka voisivat laukaista set -e on sleep (break erityinen sisäänrakennettu komento lopettaa vian useimmissa kuoreissa, komennot iv id = set -e, n=... tai && -kohdan vasemmalla puolella

voi epäonnistua, jos n on vain luku -muodossa, mutta se sulkisi komentosarjan ilman set -e), niin että tulkinta kuulostaa melko epätodennäköiseltä. Olen samaa mieltä siitä, että kysymys on muotoiltu huonosti.

Vastaa

Voit poistua komentosarjasta missä tahansa avainsanalla exit. Voit myös määrittää poistumiskoodin osoittamaan muille ohjelmille, että komentosarjasi epäonnistui tai kuinka exit 1 tai exit 2 jne. (Tavanomaisesti poistumistunnus 0 on menestys ja mikä tahansa suurempi kuin 0 tarkoittaa epäonnistumista; kuitenkin myös sopimuksen mukaan , poistumiskoodit, jotka ovat yli 127, on varattu epänormaalille päättämiselle (esim. signaalilla).

Yleinen rakenne poistumiseen vikaantumisen yhteydessä on

if [ failure condition ]; then exit n fi 

sopivilla failure condition ja n kanssa. Mutta tietyissä tilanteissa voit edetä toisin. Tapauksessasi tulkitsen kysymyksesi, että jos jokin viidestä gksu -kutsusta epäonnistuu, tarkoitat lopettaa. Yksi tapa on käyttää tällaista toimintoa

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

ja sitten kutsua silmukka try_command.

On (enemmän) edistyneempiä tai hienostuneempia tapoja vastata kysymykseesi. Yllä oleva ratkaisu on kuitenkin helpompi aloittelijoille kuin Stephanen ratkaisu.

Vastaa

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

exit sulkee komentosarjan, ellei sitä kutsuta alikuoressa. Jos komentosarjan kyseinen osa on alikuoressa, esimerkiksi koska se on (...) tai $(...) tai putkilinjan sisällä , niin se poistuu vain kyseisestä alikuoresta .

Jos siinä tapauksessa haluat komentosarjan poistuvan alikuoren lisäksi, sinä ” Minun täytyy kutsua exit, kun kyseinen alikuori poistuu.

Esimerkiksi täällä, jossa on 2 sisäkkäistä alihakutasoa:

( 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 

Siitä voi tulla hankalampaa, jos alikuori on osa putkistoa. bash -laitteessa on erityinen $PIPESTATUS -taulukko, joka on samanlainen kuin zsh ”s $pipestatus joka voi auttaa sinua tässä:

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

vastaus

Trap suorittaa toiminnon vastaanotettuaan signaalin.

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 

Suorita tämä ja anna sen poistua normaalisti. Se tarttuu signaaliin 0.

EXIT 

Suorita se uudelleen ja keskeytä painikkeella ^ C. Se tarttuu sekä signaaliin 2 että signaaliin 0.

CTL-C EXIT 

Poistumistila, joka ei ole nolla, tarttuu ERR: ään

ERR EXIT 

Vastaa

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

Vastaa

Sähköpostiosoitettasi ei julkaista. Pakolliset kentät on merkitty *