Hvordan kan jeg gjøre noe slikt i bash?
if "`command` returns any error"; then echo "Returned an error" else echo "Proceed..." fi
Svar
Hvordan gjøre noe betinget hvis en kommando lyktes eller mislyktes
Det er nøyaktig hva bash «s if
uttalelse gjør:
if command ; then echo "Command succeeded" else echo "Command failed" fi
Legger til informasjon fra kommentarer: du don» t trenger å bruke [
… ]
syntaksen i dette tilfellet. [
er i seg selv en kommando, nesten tilsvarer test
. Det er sannsynligvis den vanligste kommandoen å bruke i en if
, som kan føre til antagelsen om at det er en del av skallets syntaks. Men hvis du vil teste om en kommando lyktes eller ikke, bruk selve kommandoen direkte med if
, som vist ovenfor.
Kommentarer
Svar
For små ting at du vil skje hvis en shell-kommando fungerer, kan du bruke &&
-konstruksjonen:
rm -rf somedir && trace_output "Removed the directory"
Tilsvarende for små ting som du vil skal skje når en shell-kommando mislykkes, kan du bruke ||
:
rm -rf somedir || exit_on_error "Failed to remove the directory"
Eller begge deler
rm -rf somedir && trace_output "Removed the directory" || exit_on_error "Failed to remove the directory"
Det er sannsynligvis uklokt å gjøre veldig mye med disse konstruksjonene, men de kan av og til gjøre strømmen av kontroll mye tydeligere.
Kommentarer
- De er kortere og (i det minste i noen skall) raskere. Jeg grøsser med å huske et monster Ultrix installasjonsskript skrevet med bare disse betingede konstruksjonene jeg en gang prøvde dechiffrere …
Svar
Sjekk verdien på $?
, som inneholder resultatet av å utføre den nyeste kommandoen / funksjonen:
#!/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
Kommentarer
- Selv om det er teknisk riktig (og dermed ikke garanterer en nedstemning), er det ‘ bruker ikke Bash ‘ s
if
idiom. Jeg foretrekker Keith Thompson ‘ s svar. - Det er fordeler med dette uttrykket – det bevarer returverdien. I det hele tatt synes jeg denne er kraftigere, men mer detaljert. det ‘ er også lettere å lese.
- Hva er » Bash ‘ s if idiom «?
- @Nowaker Det faktum at det eneste formålet med
if
er å gjøre dette. Flytkontrollforholdene i Bash undersøker alle$?
bak kulissene; at ‘ er hva de gjør. Eksplisitt å undersøke verdien bør være unødvendig i de aller fleste tilfeller, og er vanligvis et nybegynnermotiv. - Jeg foretrekker dette for lesbarhet. Hovedkommandoen er vanligvis veldig lang. Å plassere den i en » hvis » utsagn gir dårlig lesbarhet.
Svar
Dette fungerte for meg:
command && echo "OK" || echo "NOK"
hvis command
lykkes, så blir echo "OK"
utført, og siden den lykkes, stopper utførelsen der. Ellers hoppes &&
over, og echo "NOK"
kjøres.
Kommentarer
- Hvis du vil gjøre noe hvis det mislykkes, og bevare utgangskoden (for å vise i ledeteksten eller teste i et skript), kan du gjøre dette:
command && echo "OK" || c=$?; echo "NOK"; $(exit $c)
- @ Sam-Hasler: shouldn ‘ t that be
command && echo "OK" || (c=$?; echo "NOK"; (exit $c))
? - Også hvis
echo "OK"
delen kunne selv mislykkes, så er dette bedre:command && (echo "OK"; exit 0) || (c=$?; echo "NOK"; (exit $c))
- @ jrw32982, Nice, jeg ‘ har brukt den tidligere konstruksjonen, men ikke sistnevnte.
- Det virkelige svaret er i kommentarene, takk alle sammen!
Svar
Det skal bemerkes at if...then...fi
og &&
/ ||
type tilnærming omhandler exit status returnert med kommando vi vil teste (0 på suksess); noen kommandoer gir imidlertid ikke en exit-status som ikke er null hvis kommandoen mislyktes eller ikke kunne håndtere input. Dette betyr at den vanlige if
og &&
/ ||
tilnærmingene ikke vil fungere for dem bestemte kommandoer.
For eksempel, på Linux GNU file
avsluttes fortsatt med 0 hvis den mottok en ikke-eksisterende fil som argument og find
kunne ikke finne den angitte filbrukeren.
$ 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
I slike tilfeller er en mulig måte vi kan håndtere situasjonen på å lese stderr
/ stdin
meldinger, f.eks. de som returnerte med file
-kommando, eller analyserte kommandoen som i find
. For det formålet kan case
uttalelse brukes.
$ 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
Svar
Den mest feilutsatte jeg kunne komme på var:
- Først får du verdien. Anta at du gjør noe sånt som:
RR=$?
Nå, for ikke bare denne situasjonen, men andre du kan møte, vurdere:
definert variabel:
$ AA=1 ; if (( "10#0${AA}" == 1 )) ; then echo yes ; else echo no ; fi
Svar: ja
$ AA=1 ; if (( "10#0${AA}" != 1 )) ; then echo yes ; else echo no ; fi
Svar: nei
udefinert variabel:
$ AA=1 ; if (( "10#0${BB}" == 1 )) ; then echo yes ; else echo no ; fi
Svar: nei
$ AA=1 ; if (( "10#0${BB}" != 1 )) ; then echo yes ; else echo no ; fi
Svar: ja
$ AA=1 ; if (( "10#0${BB}" == 0 )) ; then echo yes ; else echo no ; fi
Svar: ja
Dette forhindrer alle slags feil.
Du er sannsynligvis klar over alle syntaksen, men her noen tips:
- Bruk anførselstegn. Unngå at
"blank"
skal værenothing
. - Den nye moderne notasjonen for variabler er
${variable}
. - Hvis du legger til et null sammenkoblet før nummeret ditt, unngår du også «intet nummer i det hele tatt».
- Men vent, å legge til et null gjør at tallet blir
base-8
. Du får en feil som:-
value too great for base (error token is "08")
for tall over7
. Det er da10#
spiller inn: -
10#
tvinger tallet til å værebase-10
.
-
Svar
Du kan gjøre dette:
if ($( ping 4.4.4.4 -c1 > /dev/null )) ; then echo "ping response succsess!!!" fi
Kommentarer
- Det fungerer, men er innviklet. Du ‘ kjører ping i en subshell av en subshell, blir utdata fra
ping
fanget med tanke på å kjøre den som en kommando. Men fordi utdataene blir omdirigert til / dev / null, vil det alltid være den tomme strengen. Så du ‘ kjører ingenting i en subshell, noe som betyr at den forrige utgangsstatusen (av subshell for kommandosubstitusjon, som er av ping), blir beholdt. Den riktige måten er åpenbartif ping ...; then
her.
Svar
Som nevnt andre steder i denne tråden, svarer det opprinnelige spørsmålet i seg selv. Her er en illustrasjon som viser at if
forhold også kan være nestet.
Dette eksemplet bruker if
for å sjekke om en fil eksisterer, og om den er en vanlig fil. Hvis disse forholdene er oppfylte, sjekk om den har en størrelse som er større enn 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
Kommentarer
- Det er det svaret ditt gjør, men svaret ditt adresserer ikke spørsmålet.
- @JeffSchaller, takk for notatet ditt. Jeg redigerte innlegget mitt for å inkludere en referanse til spørsmålet.
Svar
#!/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
Kommentarer
- Dette ser ganske mye ut som eksisterende aksepterte svar ; vennligst attributt arbeid deg ‘ gjenbruk, eller legg til egen innsats i svarene dine.
Svar
Dette kan gjøres ganske enkelt på denne måten da $?
gir deg statusen av siste kommando utført.
Så det kan være
#!/bin/sh ... some command ... if [ $? == 0 ] ; then echo "<the output message you want to display>" else echo "<failure message>" fi
Kommentarer
- Nedstemme: Dette omformulerer ganske enkelt et tidligere svar som med rette har fått kritikk for å være unidiomatisk.
- Egentlig var dette akkurat det jeg lette etter fordi jeg ‘ prøver for å gjøre » -kommandoen » mislykkes skriptet som en del av » set -e » som den ikke ‘ t hvis den ‘ er en del av if.Dette bør ikke ‘ ikke nedstemmes.
then
på en egen linje.if ! command ; then ... ; fi
.[
er i seg selv en kommando, og det ‘ er ikke nødvendig i dette tilfellet.if [ ! command ]
utfører ‘ tcommand
; den behandlercommand
som en streng og behandler den som sant fordi den har en lengde som ikke er null.[
er et synonym fortest
-kommandoen