Hvordan kan jeg gøre noget lignende i bash?
if "`command` returns any error"; then echo "Returned an error" else echo "Proceed..." fi
Svar
Sådan gør du betinget, hvis en kommando lykkedes eller mislykkedes
Det er nøjagtigt hvad bash “s if
udsagn gør:
if command ; then echo "Command succeeded" else echo "Command failed" fi
Tilføjelse af oplysninger fra kommentarer: du don” t skal bruge [
… ]
syntaksen i dette tilfælde. [
er i sig selv en kommando, der næsten svarer til test
. Det er sandsynligvis den mest almindelige kommando til brug i en if
, som kan føre til den antagelse, at det er en del af skalens syntaks. Men hvis du vil teste, om en kommando lykkedes eller ej, skal du bruge selve kommandoen direkte med if
, som vist ovenfor.
Kommentarer
Svar
For små ting at du vil ske, hvis en shell-kommando fungerer, kan du bruge &&
-konstruktionen:
rm -rf somedir && trace_output "Removed the directory"
Tilsvarende for små ting, som du ønsker skal ske, når en shell-kommando mislykkes, kan du bruge ||
:
rm -rf somedir || exit_on_error "Failed to remove the directory"
Eller begge dele
rm -rf somedir && trace_output "Removed the directory" || exit_on_error "Failed to remove the directory"
Det er sandsynligvis uklogt at gøre meget med disse konstruktioner, men de kan til tider gøre strømmen af kontrol meget klarere.
Kommentarer
- De er kortere og (i det mindste i nogle skaller) hurtigere. Jeg ryster når jeg husker et monster-Ultrix installations script skrevet med netop disse betingede konstruktioner, som jeg engang forsøgte dechiffrere …
Svar
Kontroller værdien af $?
, som indeholder resultatet af udførelse af den nyeste kommando / funktion:
#!/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
- Selvom det er teknisk korrekt (og således ikke berettiger en nedstemning), er det ‘ bruger ikke Bash ‘ s
if
idiom. Jeg foretrækker Keith Thompson ‘ s svar. - Dette udtryk har fordele – det bevarer returværdien. Alt i alt finder jeg, at denne er mere magtfuld, dog mere detaljeret. det ‘ er også lettere at læse.
- Hvad er ” Bash ‘ s hvis idiom “?
- @Nowaker Det faktum, at det eneste formål med
if
er at gøre det her. Flowkontrolforholdene i Bash undersøger alle$?
bag kulisserne; at ‘ er, hvad de gør. Eksplicit at undersøge dens værdi burde være unødvendig i langt de fleste tilfælde og er normalt et begynderantipatron. - Jeg foretrækker dette for læsbarhed. Hovedkommandoen er typisk rigtig lang. At lægge det i en ” hvis ” udsagn giver dårlig læsbarhed.
Svar
Dette fungerede for mig:
command && echo "OK" || echo "NOK"
hvis command
lykkes, så udføres echo "OK"
, og da det er vellykket, stopper udførelsen der. Ellers springes &&
over, og echo "NOK"
udføres.
Kommentarer
- Hvis du vil gøre noget, hvis det mislykkes, og bevare udgangskoden (for at vise i kommandoprompten eller teste i et script), kan du gøre dette:
command && echo "OK" || c=$?; echo "NOK"; $(exit $c)
- @ Sam-Hasler: shouldn ‘ t der er
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 brugt den tidligere konstruktion, men ikke sidstnævnte.
- Det rigtige svar er i kommentarerne, tak alle sammen!
Svar
Det skal bemærkes, at if...then...fi
og &&
/ ||
type tilgang beskæftiger sig med exit status returneret med kommando, vi vil teste (0 efter succes); nogle kommandoer returnerer dog ikke en status, der ikke er nul, hvis kommandoen mislykkedes eller ikke kunne håndtere input. Dette betyder, at den sædvanlige if
og &&
/ ||
-tilgange ikke fungerer for dem bestemte kommandoer.
For eksempel, på Linux GNU file
afsluttes stadig med 0, hvis den modtog en ikke-eksisterende fil som argument og find
kunne ikke finde den angivne filbruger.
$ 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 sådanne tilfælde er en mulig måde, vi kan håndtere situationen på, ved at læse stderr
/ stdin
meddelelser, f.eks. dem, der vendte tilbage med file
kommando, eller analyser output af kommandoen som i find
. Til dette formål kunne case
udsagn bruges.
$ 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 udsatte fejl, jeg kunne komme med var:
- Først skal du få værdien. Antag at du gør noget som:
RR=$?
Nu for ikke kun denne situation, men andre du måske står over for, overvej:
defineret 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: nej
udefineret variabel:
$ AA=1 ; if (( "10#0${BB}" == 1 )) ; then echo yes ; else echo no ; fi
Svar: nej
$ 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 off-fejl.
Du er sandsynligvis opmærksom på al syntaks, men her nogle tip:
- Brug anførselstegn. Undgå at
"blank"
skal værenothing
. - Den nye moderne notation for variabler er
${variable}
. - Tilføjelse af et nul sammenkædet før dit nummer undgår også “slet ikke noget”.
- Men vent, hvis du tilføjer et nul, bliver tallet til
base-8
. Du får en fejl som:-
value too great for base (error token is "08")
for tal over7
. Det er når10#
kommer i spil: -
10#
tvinger tallet til at værebase-10
.
-
Svar
Du kan gøre dette:
if ($( ping 4.4.4.4 -c1 > /dev/null )) ; then echo "ping response succsess!!!" fi
Kommentarer
- Det fungerer, men er indviklet. Du ‘ kører ping i en subshell af en subshell, output fra
ping
fanges med henblik på at køre den som en kommando. Men fordi output omdirigeres til / dev / null, vil det altid være den tomme streng. Så du ‘ kører intet i en subshell, hvilket betyder, at den forrige exit-status (af kommandosubstitution subshell, det vil sige ping) bevares. Den rigtige måde er åbenbartif ping ...; then
her.
Svar
Som nævnt andetsteds i denne tråd, svarer det originale spørgsmål grundlæggende på sig selv. Her er en illustration, der viser, at if
betingelser også kan være indlejrede.
Dette eksempel bruger if
til at kontrollere, om en fil findes, og om den er en almindelig fil. Hvis disse betingelser er sande, skal du kontrollere, om den har en størrelse, der er større end 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 hvad dit svar gør, men dit svar adresserer ikke spørgsmålet.
- @JeffSchaller, tak for din note. Jeg redigerede mit indlæg for at inkludere en henvisning til spørgsmå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 ligner en smule det eksisterende accepterede svar ; bedes attribut arbejde med dig ‘ genbruger eller tilføj din egen indsats i dine svar.
Svar
Dette kan gøres simpelthen på denne måde, da $?
giver dig status af den sidste kommando, der blev udført.
Så det kunne være
#!/bin/sh ... some command ... if [ $? == 0 ] ; then echo "<the output message you want to display>" else echo "<failure message>" fi
Kommentarer
- Downvote: Dette parafraserer simpelthen et tidligere svar, som med rette har modtaget kritik for at være unidiomatisk.
- Faktisk var det præcis det, jeg ledte efter, fordi jeg ‘ prøver for at få ” kommandoen ” mislykkes scriptet som en del af ” set -e ” som det ikke ‘ t hvis det ‘ er en del af if.Dette bør ikke ‘ ikke nedstemmes.
then
på en separat linje.if ! command ; then ... ; fi
.[
er i sig selv en kommando, og det ‘ er ikke nødvendigt i dette tilfælde.if [ ! command ]
udfører ‘ tcommand
; det behandlercommand
som en streng og behandler det som sandt, fordi det har en længde, der ikke er nul.[
er et synonym fortest
kommando