Hur vill jag göra något om ett kommando lyckades eller misslyckades

Hur kan jag göra något liknande i bash?

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

Svar

Hur man vill göra något om ett kommando lyckades eller misslyckades

Det är exakt vad bash ”s if uttalande gör:

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

Lägga till information från kommentarer: du don” t behöver använda [] syntax i detta fall. [ är i sig ett kommando, nästan lika med test. Det är förmodligen det vanligaste kommandot att använda i en if, till antagandet att det är en del av skalets syntax. Men om du vill testa om ett kommando lyckades eller inte, använd själva kommandot direkt med if, som visas ovan.

Kommentarer

  • Observera att semikolon är viktigt.
  • Eller så kan du bara lägga then på en separat rad.
  • @Joe: Jag tror att du menar if ! command ; then ... ; fi. [ är i sig ett kommando, och det ’ behövs inte i det här fallet.
  • @Joe: Mitt sätt har också dygden att vara korrekt. if [ ! command ] ’ t kör command; det behandlar command som en sträng och behandlar det som sant eftersom det har en längd som inte är noll. [ är en synonym för kommandot test
  • Hoppsan. Du ’ är korrekt.

Svar

För små saker att du vill hända om ett skalkommando fungerar kan du använda && -konstruktionen:

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

På samma sätt för små saker som du vill ska hända när ett skalkommando misslyckas kan du använda ||:

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

Eller båda

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

Det är förmodligen oklokt att göra mycket med dessa konstruktioner, men de kan ibland göra kontrollflödet mycket tydligare.

Kommentarer

  • De är kortare och (åtminstone i vissa skal) snabbare. Jag ryser ihåg ett monster Ultrix installationsskript skrivet med just dessa villkorliga konstruktioner som jag en gång försökte dechiffrera …

Svar

Kontrollera värdet på $?, som innehåller resultatet av det senaste kommandot / funktionen:

#!/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

  • Även om det är tekniskt korrekt (och därmed inte motiverar en nedröstning), ’ använder inte Bash ’ s if idiom. Jag föredrar Keith Thompson ’ s svar.
  • Det finns fördelar med detta uttryck – det bevarar returvärdet. Sammantaget tycker jag att den här är mer kraftfull, även om den är mer detaljerad. det ’ är också lättare att läsa.
  • Vad är ” Bash ’ s if idiom ”?
  • @Nowaker Det faktum att det enda syftet med if är att göra detta. Flödeskontrollförhållandena i Bash undersöker alla $? bakom kulisserna; att ’ är vad de gör. Att uttryckligen undersöka dess värde borde vara onödigt i de allra flesta fall och är vanligtvis en nybörjare motmönster.
  • Jag föredrar detta för läsbarhet. Huvudkommandot är vanligtvis riktigt långt. Att placera det i ett ” om ” uttalande ger dålig läsbarhet.

Svar

Detta fungerade för mig:

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

om command lyckas, så körs echo "OK", och eftersom det lyckas slutar exekveringen där. Annars hoppas && och echo "NOK" körs.

Kommentarer

  • Om du vill göra något om det misslyckas och bevara utgångskoden (för att visas i kommandotolken eller testa i ett skript) kan du göra detta: command && echo "OK" || c=$?; echo "NOK"; $(exit $c)
  • @ Sam-Hasler: ska inte ’ t that be command && echo "OK" || (c=$?; echo "NOK"; (exit $c))?
  • Och om echo "OK" -delen kunde själv misslyckas, då är det bättre: command && (echo "OK"; exit 0) || (c=$?; echo "NOK"; (exit $c))
  • @ jrw32982, Trevligt, jag ’ har använt den tidigare konstruktionen, men inte det senare.
  • Det riktiga svaret finns i kommentarerna, tack alla!

Svar

Det bör noteras att if...then...fi och && / || typ av tillvägagångssätt handlar om utgångsstatus som returneras med kommando vi vill testa (0 efter framgång); Vissa kommandon returnerar dock inte en utgångsstatus som inte är noll om kommandot misslyckades eller inte kunde hantera inmatning. Detta innebär att de vanliga if och && / || -inställningarna inte fungerar för dem specifika kommandon.

Till exempel, på Linux GNU file avslutas fortfarande med 0 om den fick en icke-existerande fil som argument och find kunde inte hitta den angivna filanvändaren.

$ 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ådana fall är ett potentiellt sätt att hantera situationen genom att läsa stderr / stdin meddelanden, t.ex. de som returnerade med file kommando, eller analysera kommandot som i find. För detta ändamål kan case uttalande användas.

$ 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

Det mest felbenägna jag kunde komma på var:

  • Först får du värdet. Antag att du gör något som:

RR=$?

Nu, inte bara för den här situationen, utan andra du kan möta, överväga:

definierad 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

odefinierad 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

Detta förhindrar alla slags off-fel.

Du är nog medveten om all syntax, men här några tips:

  • Använd citat. Undvik att "blank" ska vara nothing.
  • Den nya moderna notationen för variabler är ${variable}.
  • Att lägga till en noll sammanfogad före ditt nummer undviker också ”inget nummer alls”.
  • Men vänta, lägg till en noll gör att numret blir base-8. Du får ett fel som:
    • value too great for base (error token is "08") för siffror över 7. Det är då 10# spelar in:
    • 10# tvingar talet att vara base-10.

Svar

Du kan göra detta:

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

Kommentarer

  • Det fungerar men är invecklat. Du ’ kör ping i en subshell av en subshell, utdata från ping fångas för att köra den som ett kommando. Men eftersom utdata omdirigeras till / dev / null kommer det alltid att vara den tomma strängen. Så du ’ kör inget i en subshell, vilket innebär att den tidigare utgångsstatusen (för subshell för kommandosubstitution, det vill säga ping) kommer att behållas. Självklart är rätt sätt if ping ...; then här.

Svar

Som nämnts någon annanstans i denna tråd svarar den ursprungliga frågan i princip på sig själv. Här är en illustration som visar att if villkor också kan vara kapslade.

Detta exempel använder if för att kontrollera om en fil finns och om det är en vanlig fil. Om dessa villkor är sanna, kontrollera om den har en storlek som är större än 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 är vad ditt svar gör, men ditt svar tar inte upp frågan.
  • @JeffSchaller, tack för din anteckning. Jag redigerade mitt inlägg för att inkludera en hänvisning till frågan.

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

Svar

Detta kan göras helt enkelt på det här sättet eftersom $? ger dig status av det senaste kommandot som kördes.

Så det kan vara

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

Kommentarer

  • Downvote: Detta omformar helt enkelt ett tidigare svar som med rätta har fått kritik för att vara unidiomatiskt.
  • Egentligen var det precis det jag letade efter eftersom jag ’ försöker för att göra ” -kommandot ” misslyckas manuset som en del av ” set -e ” som den inte ’ t om den ’ är en del av if.Detta ska inte ’ nedröstas.

Lämna ett svar

Din e-postadress kommer inte publiceras. Obligatoriska fält är märkta *