Kuinka ehdollisesti tehdä jotain, jos komento onnistui tai epäonnistui

Kuinka voin tehdä jotain tällaista bashissa?

if "`command` returns any error"; then echo "Returned an error" else echo "Proceed..." fi 

Vastaa

Kuinka ehdollisesti tehdä jotain, jos komento onnistui tai epäonnistui

Se on mitä bash ”s if -lauseke tekee:

if command ; then echo "Command succeeded" else echo "Command failed" fi 

Tietojen lisääminen kommenteista: et et” t täytyy tässä tapauksessa käyttää [] -syntaksia. [ on itse komento, melkein vastaava kuin test. Se on todennäköisesti yleisin komento, jota käytetään if: ssä, joka voi johtaa oletukseen, että se on osa kuoren syntaksia. Mutta jos haluat testata, onnistuiko komento vai ei, käytä komentoa itse suoraan if -näppäimen kanssa, kuten yllä on esitetty.

Kommentit

  • Huomaa, että puolipiste on tärkeä.
  • Tai voit vain laittaa then erilliselle riville.
  • @Joe: Luulen, että tarkoitat if ! command ; then ... ; fi. [ on itse komento, eikä sitä ’ tarvita tässä tapauksessa.
  • @Joe: Oma tapa on myös hyve olla oikea. if [ ! command ] ei ’ t suorita command; se käsittelee command merkkijonona ja pitää sitä totta, koska sen pituus ei ole nolla. [ on synonyymi komennolle test
  • Hups. Olet ’ oikeassa.

Vastaa

Pienistä asioista jonka haluat tapahtua, jos komentokäsky toimii, voit käyttää && -rakennetta:

rm -rf somedir && trace_output "Removed the directory" 

Vastaavasti pieniä asioita, jotka haluat tapahtua, kun komento epäonnistuu, voit käyttää ||:

rm -rf somedir || exit_on_error "Failed to remove the directory" 

Tai molempia

rm -rf somedir && trace_output "Removed the directory" || exit_on_error "Failed to remove the directory" 

Näihin rakenteisiin ei todennäköisesti ole järkevää tehdä paljon, mutta ne voivat toisinaan tehdä ohjausvirrasta paljon selkeämmän.

Kommentit

  • Ne ovat lyhyempiä ja (ainakin joissakin säiliöissä) nopeampia. Minusta vapisee muistaa hirviö Ultrix -asennuskoodin, joka on kirjoitettu juuri näillä ehdollisilla rakenteilla, joita yritin tulkita …

Vastaa

Tarkista arvon $?, joka sisältää viimeisimmän komennon / toiminnon suorittamisen tuloksen:

#!/bin/bash echo "this will work" RESULT=$? if [ $RESULT -eq 0 ]; then echo success else echo failed fi if [ $RESULT == 0 ]; then echo success 2 else echo failed 2 fi 

Kommentit

  • Vaikka se on teknisesti oikein (eikä näin ollen oikeuta aliarvostusta), se ’ eivät käytä Bash ’ s if idioomia. Pidän parempana Keith Thompsonin ’ vastauksesta.
  • Tällä idiomalla on etuja – se säilyttää palautusarvon. Kaiken kaikkiaan mielestäni tämä on voimakkaampi, vaikkakin sanallisempi. se ’ on myös helpompi lukea.
  • Mikä on ” Bash ’ s jos idiomi ”?
  • @Nowaker Se, että if -sivuston ainoa tarkoitus on Tämä. Bashin virtauksen säätöolosuhteet tutkivat kaikki $? kulissien takana; että ’ tekee sitä, mitä he tekevät. Sen arvon nimenomaisen tutkimisen ei pitäisi olla tarpeetonta suurimmassa osassa tapauksia, ja se on yleensä aloittelijan vastainen malli.
  • Pidän parempana tätä luettavuuden vuoksi. Pääkomento on tyypillisesti todella pitkä. Laittamalla se ” -elementtiin, jos ” -lauseke heikentää luettavuutta.

Vastaus

Tämä toimi minulle:

command && echo "OK" || echo "NOK" 

if command onnistuu, sitten suoritetaan echo "OK", ja koska se onnistuu, suoritus pysähtyy siellä. Muussa tapauksessa && ohitetaan ja echo "NOK" suoritetaan.

Kommentit

  • Jos haluat tehdä jotain, jos se epäonnistuu, ja säilytä poistumiskoodin (jotta se voidaan näyttää komentokehotteessa tai testata komentosarjassa), voit tehdä tämän: command && echo "OK" || c=$?; echo "NOK"; $(exit $c)
  • @ Sam-Hasler: shouldn ’ t, jotka ovat command && echo "OK" || (c=$?; echo "NOK"; (exit $c))?
  • Lisäksi, jos echo "OK" osa voisi itse epäonnistuu, niin tämä on parempi: command && (echo "OK"; exit 0) || (c=$?; echo "NOK"; (exit $c))
  • @ jrw32982, Nizza, olen ’ käyttänyt entistä rakennetta, mutta ei jälkimmäistä.
  • Todellinen vastaus on kommenteissa, kiitos kaikille!

vastaus

On huomattava, että if...then...fi ja && / || -tyyppinen lähestymistapa käsittelee poistumistilaa, jonka palauttaa komento, jonka haluamme testata (0 onnistumisessa); jotkut komennot eivät kuitenkaan palauta nollasta poikkeavaa poistumistilaa, jos komento epäonnistui tai eivät pysty käsittelemään syötettä. Tämä tarkoittaa, että tavalliset if ja && / || lähestymistavat eivät toimi niille tietyt komennot.

Esimerkiksi Linuxissa GNU file poistuu edelleen 0: lla, jos se sai argumenttina olemattoman tiedoston ja find ei löytynyt määritettyä tiedoston käyttäjää.

$ find . -name "not_existing_file" $ echo $? 0 $ file ./not_existing_file ./not_existing_file: cannot open `./not_existing_file" (No such file or directory) $ echo $? 0 

Tällaisissa tapauksissa yksi mahdollinen tapa hoitaa tilanne on lukemalla stderr / stdin viestit, esim. ne, jotka palasivat file -komennolla tai jäsensivät komennon lähdön kuten kohdassa find. Tätä tarkoitusta varten case -lauseketta voitaisiin käyttää.

$ file ./doesntexist | while IFS= read -r output; do > case "$output" in > *"No such file or directory"*) printf "%s\n" "This will show up if failed";; > *) printf "%s\n" "This will show up if succeeded" ;; > esac > done This will show up if failed $ find . -name "doesn"texist" | if ! read IFS= out; then echo "File not found"; fi File not found 

Vastaa

Eniten virhealttiuksia, joita keksin, oli:

  • Hanki ensin arvo. Oletetaan, että teet jotain seuraavista:

RR=$?

Nyt, paitsi tähän tilanteeseen, myös muihin, joita saatat kohdata, harkitse:

määritelty muuttuja:

$ AA=1 ; if (( "10#0${AA}" == 1 )) ; then echo yes ; else echo no ; fi

Vastaus: kyllä

$ AA=1 ; if (( "10#0${AA}" != 1 )) ; then echo yes ; else echo no ; fi

Vastaus: ei

määrittelemätön muuttuja:

$ AA=1 ; if (( "10#0${BB}" == 1 )) ; then echo yes ; else echo no ; fi

Vastaus: ei

$ AA=1 ; if (( "10#0${BB}" != 1 )) ; then echo yes ; else echo no ; fi

Vastaus: kyllä

$ AA=1 ; if (( "10#0${BB}" == 0 )) ; then echo yes ; else echo no ; fi

Vastaus: kyllä

Tämä estää kaikenlaisia virheitä.

Olet todennäköisesti tietoinen kaikesta syntaksista, mutta tässä on joitain vinkkejä:

  • Käytä lainausmerkkejä. Vältä "blank" olemista nothing.
  • Uusi muuttujien uusi merkintätapa on ${variable}.
  • Numeron liittämisen ennen ketjun yhdistämistä vältetään myös ”ei numeroa ollenkaan”.
  • Mutta odota, kun lisäät nollan, numerosta tulee base-8. Saat seuraavanlaisen virheen:
    • value too great for base (error token is "08") numeroille, jotka ovat 7. Silloin 10# tulee esiin:
    • 10# pakottaa luvun olemaan base-10.

Vastaa

Voit tehdä tämän:

if ($( ping 4.4.4.4 -c1 > /dev/null )) ; then echo "ping response succsess!!!" fi 

Kommentit

  • Se toimii, mutta on sekava. ’ suoritat pingin alikuoren alikuoressa, ping -lähtö kaapataan, koska se suoritetaan komentona. Mutta koska lähtö ohjataan kohtaan / dev / null, se on aina tyhjä merkkijono. Joten ’ ei ole käynnissä mitään alikuoressa, mikä tarkoittaa, että edellinen (komentojen korvaavan alikuoren eli pingin poistumistila) säilytetään. Oikea tapa on tietysti if ping ...; then täällä.

Vastaa

Kuten muualla tässä säikeessä todettiin, alkuperäinen kysymys vastaa pohjimmiltaan itseään. Tässä on kuva, joka osoittaa, että if -olosuhteet voivat olla myös sisäkkäisiä.

Tässä esimerkissä if tarkistaa, onko tiedosto olemassa ja onko se tavallinen tiedosto. Jos nämä ehdot täyttyvät, tarkista onko sen koko suurempi kuin 0.

#!/bin/bash echo "Which error log are you checking today? " read answer if [ -f /opt/logs/$answer*.errors ] then if [ -s /opt/logs/$answer*.errors ] then echo "Content is present in the $answer error log file." else echo "No errors are present in the $answer error log file." fi else echo "$answer does not have an error log at this time." fi 

Kommentit

  • Näin vastauksesi tekee, mutta vastauksesi ei koske kysymystä.
  • @JeffSchaller, kiitos huomautuksestasi. Muokkasin viestiä sisältäen viittauksen kysymykseen.

Vastaa

#!/bin/bash if command-1 ; then echo "command-1 succeeded and now running from this block command-2" command-2 else echo "command-1 failed and now running from this block command-3" command-3 fi 

kommentit

vastaus

Tämä voidaan tehdä yksinkertaisesti tällä tavalla, koska $? antaa sinulle tilan viimeisestä suoritetusta komennosta.

Joten se voi olla

#!/bin/sh ... some command ... if [ $? == 0 ] ; then echo "<the output message you want to display>" else echo "<failure message>" fi 

kommentti

  • Downvote: Tämä yksinkertaisesti muotoilee aikaisemman vastauksen, joka on oikeutetusti saanut kritiikkiä yksidomaattisuudesta.
  • Olin itse asiassa juuri sitä, mitä etsin, koska yritin saada komento ” ” epäonnistumaan komentosarjassa osana ” set -e ” jota se ei ’ t, jos se ’ on osa if.Tätä ei pidä äänestää ’.

Vastaa

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