Hoe kan ik zoiets doen in bash?
if "`command` returns any error"; then echo "Returned an error" else echo "Proceed..." fi
Antwoord
Hoe je voorwaardelijk iets kunt doen als een commando is geslaagd of mislukt
Dat is precies wat bash “s if
statement doet:
if command ; then echo "Command succeeded" else echo "Command failed" fi
Informatie uit reacties toevoegen: je don” t moet in dit geval de [
… ]
syntaxis gebruiken. [
is zelf een commando, bijna gelijk aan test
. Het is waarschijnlijk het meest gebruikte commando in een if
, wat kan leiden in de veronderstelling dat het deel uitmaakt van de syntaxis van de shell. Maar als je wilt testen of een commando geslaagd is of niet, gebruik het commando zelf dan direct met if
, zoals hierboven getoond.
Opmerkingen
Antwoord
Voor kleine dingen die je wilt laten gebeuren als een shell-commando werkt, kun je het &&
construct gebruiken:
rm -rf somedir && trace_output "Removed the directory"
Evenzo voor kleine dingen die u wilt laten gebeuren als een shell-commando mislukt, kunt u ||
:
rm -rf somedir || exit_on_error "Failed to remove the directory"
of beide gebruiken
rm -rf somedir && trace_output "Removed the directory" || exit_on_error "Failed to remove the directory"
Het is waarschijnlijk onverstandig om veel met deze constructies te doen, maar ze kunnen bij gelegenheid de stroom van controle een stuk duidelijker maken.
Reacties
- Ze zijn korter en (tenminste in sommige shells) sneller. Ik huiver als ik me een monster Ultrix-installatiescript herinner dat is geschreven met alleen deze voorwaardelijke constructies die ik ooit heb geprobeerd ontcijferen …
Antwoord
Controleer de waarde van $?
, dat het resultaat bevat van het uitvoeren van de meest recente opdracht / functie:
#!/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
Reacties
- Hoewel het technisch correct is (en dus geen downvote rechtvaardigt), is het ‘ s maakt geen gebruik van Bash ‘ s
if
idioom. Ik geef de voorkeur aan Keith Thompson ‘ s antwoord. - Er zijn voordelen aan dit idioom – het behoudt de geretourneerde waarde. Al met al vind ik deze krachtiger, hoewel meer uitgebreid. het ‘ is ook gemakkelijker te lezen.
- Wat is ” Bash ‘ s if idiom “?
- @Nowaker Het feit dat het enige doel van
if
is om te doen dit. De flow control voorwaarden in Bash onderzoeken allemaal$?
achter de schermen; dat ‘ is wat ze doen. Het expliciet onderzoeken van de waarde ervan zou in de overgrote meerderheid van de gevallen niet nodig moeten zijn, en is meestal een antipatroon voor beginners. - Ik geef hier de voorkeur aan vanwege de leesbaarheid. Het hoofdcommando is meestal erg lang. Door het in een ” te plaatsen als ” -instructie slecht leesbaar is.
Antwoord
Dit werkte voor mij:
command && echo "OK" || echo "NOK"
if command
slaagt, wordt echo "OK"
uitgevoerd, en aangezien het succesvol is, stopt de uitvoering daar. Anders wordt &&
overgeslagen, en echo "NOK"
wordt uitgevoerd.
Opmerkingen
- Als je iets wilt doen als het mislukt, en bewaar de afsluitcode (om te tonen in opdrachtprompt of test in een script), u kunt dit doen:
command && echo "OK" || c=$?; echo "NOK"; $(exit $c)
- @ Sam-Hasler: shouldn ‘ t dat
command && echo "OK" || (c=$?; echo "NOK"; (exit $c))
? - En als het
echo "OK"
-gedeelte zichzelf mislukt, dan is dit beter:command && (echo "OK"; exit 0) || (c=$?; echo "NOK"; (exit $c))
- @ jrw32982, Nice, ik ‘ heb de vorige constructie gebruikt, maar niet het laatste.
- Het echte antwoord staat in de reacties, allemaal bedankt!
Antwoord
Opgemerkt moet worden dat if...then...fi
en &&
/ ||
type benadering behandelt de exitstatus die wordt geretourneerd door het commando dat we willen testen (0 bij succes); sommige commandos geven echter geen exit-status die niet gelijk is aan nul als het commando is mislukt of de invoer niet kon verwerken. Dit betekent dat de gebruikelijke if
en &&
/ ||
benaderingen niet werken voor die bepaalde commandos.
Onder Linux wordt bijvoorbeeld GNU file
nog steeds afgesloten met 0 als het een niet-bestaand bestand als argument heeft ontvangen en find
kon het door de gebruiker opgegeven bestand niet vinden.
$ 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
In dergelijke gevallen is een mogelijke manier om met de situatie om te gaan, het lezen van stderr
/ stdin
berichten, bijv. degenen die zijn geretourneerd door file
commando, of de uitvoer van het commando ontleden zoals in find
. Voor dat doel zou een case
instructie kunnen worden gebruikt.
$ 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
Antwoord
De meest foutgevoelige die ik kon bedenken was:
- Haal eerst de waarde. Stel dat u iets doet als:
RR=$?
Nu, niet alleen voor deze situatie, maar ook voor andere situaties waarmee u te maken kunt krijgen, overweeg:
gedefinieerde variabele:
$ AA=1 ; if (( "10#0${AA}" == 1 )) ; then echo yes ; else echo no ; fi
Antwoord: ja
$ AA=1 ; if (( "10#0${AA}" != 1 )) ; then echo yes ; else echo no ; fi
Antwoord: nee
ongedefinieerde variabele:
$ AA=1 ; if (( "10#0${BB}" == 1 )) ; then echo yes ; else echo no ; fi
Antwoord: nee
$ AA=1 ; if (( "10#0${BB}" != 1 )) ; then echo yes ; else echo no ; fi
Antwoord: ja
$ AA=1 ; if (( "10#0${BB}" == 0 )) ; then echo yes ; else echo no ; fi
Antwoord: ja
Dit voorkomt allerlei soorten fouten.
U kent waarschijnlijk alle syntaxis, maar hier enkele tips:
- Gebruik aanhalingstekens. Voorkom dat
"blank"
nothing
is. - De nieuwe moderne notatie voor variabelen is
${variable}
. - Het toevoegen van een nul aaneengeschakeld voor uw nummer, vermijdt ook “helemaal geen nummer”.
- Maar wacht even, als u een nul toevoegt, wordt het nummer
base-8
. U krijgt een foutmelding als:-
value too great for base (error token is "08")
voor getallen boven7
. Dat is wanneer10#
in het spel komt: -
10#
dwingt het getal .
-
Antwoord
Je kunt dit doen:
if ($( ping 4.4.4.4 -c1 > /dev/null )) ; then echo "ping response succsess!!!" fi
Reacties
- Dat werkt, maar is ingewikkeld. U ‘ voert ping uit in een subshell van een subshell, de uitvoer van
ping
wordt vastgelegd om het als een commando uit te voeren. Maar omdat de uitvoer wordt omgeleid naar / dev / null, zal dat altijd de lege string zijn. Dus je ‘ voert niets uit in een subshell, wat betekent dat de vorige exit-status (van de commandosubstitutiesubshell, dat wil zeggen van ping) behouden blijft. Het is duidelijk dat de juiste manierif ping ...; then
hier is.
Antwoord
Zoals elders in deze thread opgemerkt, beantwoordt de oorspronkelijke vraag in feite zichzelf. Hier is een illustratie die laat zien dat if
voorwaarden ook kunnen worden genest.
In dit voorbeeld wordt if
gebruikt om te controleren of een bestand bestaat en of het een gewoon bestand is. Als deze voorwaarden waar zijn, controleer dan of het een grootte heeft groter dan 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
Reacties
- Dat is wat je antwoord doet, maar je antwoord behandelt de vraag niet.
- @JeffSchaller, bedankt voor je opmerking. Ik heb mijn bericht bewerkt om een verwijzing naar de vraag op te nemen.
Antwoord
#!/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
Reacties
- Dit lijkt nogal op het bestaande geaccepteerde antwoord ; attribuut werk je ‘ opnieuw aan hergebruik, of voeg je eigen inspanningen toe aan je antwoorden.
Antwoord
Dit kan eenvoudig op deze manier worden gedaan aangezien $?
u de status geeft van de laatste uitgevoerde opdracht.
Dus het zou kunnen zijn
#!/bin/sh ... some command ... if [ $? == 0 ] ; then echo "<the output message you want to display>" else echo "<failure message>" fi
Reacties
- Downvote: dit is een parafrase van een eerder antwoord dat terecht kritiek heeft gekregen omdat het unidiomatisch is.
- Eigenlijk was dit precies wat ik zocht omdat ik ‘ m probeer om het ” commando ” het script te laten mislukken als onderdeel van ” set -e ” wat het niet ‘ doet als het ‘ een deel van de if is.Dit mag niet ‘ worden neergeslagen.
then
op een aparte regel zetten.if ! command ; then ... ; fi
bedoelt.[
is zelf een commando, en het ‘ is in dit geval niet nodig.if [ ! command ]
wordt niet ‘ uitgevoerdcommand
; het behandeltcommand
als een string en behandelt het als waar omdat het een lengte heeft die niet nul is.[
is een synoniem voor hettest
commando