Jak podmíněně udělat něco, pokud příkaz uspěl nebo selhal

Jak mohu něco takového udělat v bash?

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

Odpověď

Jak podmíněně udělat něco, pokud příkaz uspěl nebo selhal

To je přesně to, co bash „s if prohlášení dělá:

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

Přidávání informací z komentářů: neděláte Je nutné v tomto případě použít [] syntaxi. [ je sám o sobě příkazem, který je téměř ekvivalentní test. Je to pravděpodobně nejběžnější příkaz, který se používá v if, což může vést za předpokladu, že je to součást syntaxe shellu. Pokud však chcete otestovat, zda byl příkaz úspěšný nebo ne, použijte samotný příkaz přímo s if, jak je uvedeno výše.

Komentáře

  • Pamatujte, že středník je důležitý.
  • Nebo můžete then vložit na samostatný řádek.
  • @ Joe: Myslím, že myslíš if ! command ; then ... ; fi. [ je sám o sobě příkaz a v tomto případě to ‚ není potřeba.
  • @Joe: Můj způsob má také ctnost být správný. if [ ! command ] neprovádí ‚ command; považuje command za řetězec a zachází s ním jako s pravdou, protože má nenulovou délku. [ je synonymem pro příkaz test
  • Jejda. ‚ opravujete.

odpověď

na malé věci chcete-li, aby příkaz shell fungoval, můžete použít konstrukci &&:

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

Podobně pro malé věci, které se mají stát, když selže příkaz prostředí, můžete použít ||:

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

Nebo obojí

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

Je pravděpodobně nerozumné dělat s těmito konstrukty hodně, ale mohou příležitostně výrazněji objasnit tok kontroly.

Komentáře

  • Jsou kratší a (alespoň v některých skořápkách) rychlejší. Otřásám se vzpomínkou na monstrum instalačního skriptu Ultrix napsaného jen s těmito podmíněnými konstrukcemi, které jsem jednou zkoušel dešifrovat …

odpověď

zkontrolujte hodnotu $?, který obsahuje výsledek provedení nejnovějšího příkazu / funkce:

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

Komentáře

  • I když je to technicky správné (a tedy nezaručuje downvote), ‚ nepoužívá Biom ‚ s if idiom. Dávám přednost odpovědi Keitha Thompsona ‚.
  • Tento idiom má své výhody – zachovává návratovou hodnotu. Celkově mi připadá silnější, i když podrobnější. je také ‚ čitelnější.
  • Co je “ Bash ‚ s if idiom „?
  • @Nowaker Skutečnost, že jediným účelem if je dělat tento. Podmínky řízení toku v Bash všechny zkoumají $? v zákulisí; to ‚ je to, co dělají. Explicitní zkoumání jeho hodnoty by mělo být v drtivé většině případů zbytečné a obvykle jde o antipattern pro začátečníky.
  • Dávám přednost čitelnosti. Hlavní příkaz je obvykle opravdu dlouhý. Vložení do “ pokud “ prohlášení vede ke špatné čitelnosti.

Odpověď

Toto pro mě fungovalo:

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

if command uspěje, poté je proveden echo "OK" a protože je úspěšný, provádění se zastaví. Jinak je && přeskočen a echo "NOK" je spuštěn.

Komentáře

  • Pokud chcete něco udělat, pokud selže, a zachovat výstupní kód (pro zobrazení v příkazovém řádku nebo testování ve skriptu), můžete provést toto: command && echo "OK" || c=$?; echo "NOK"; $(exit $c)
  • @ Sam-Hasler: shouldn ‚ t, které mohou být command && echo "OK" || (c=$?; echo "NOK"; (exit $c))?
  • Také v případě, že by echo "OK" část mohla sama selhání, pak je to lepší: command && (echo "OK"; exit 0) || (c=$?; echo "NOK"; (exit $c))
  • @ jrw32982, Nice, použil jsem původní konstrukci ‚, ale ne to druhé.
  • Skutečná odpověď je v komentářích, děkuji všem!

Odpověď

Je třeba poznamenat, že if...then...fi a && / || typ přístupu se zabývá stavem ukončení vráceným příkazem, který chceme otestovat (0 na úspěch); některé příkazy však nevracejí nenulový stav ukončení, pokud příkaz selhal nebo se nemohl vypořádat se vstupem. To znamená, že obvyklé if a && / || přístupy pro tyto uživatele nebudou fungovat konkrétní příkazy.

Například v systému Linux GNU file stále končí s 0, pokud jako argument přijal neexistující soubor a find nelze najít zadaného uživatele souboru.

$ 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 

V takových případech je jedním z možných způsobů řešení situace přečtení stderr / stdin zprávy, např. ty, které byly vráceny příkazem file nebo analyzovat výstup příkazu jako v find. Pro tyto účely lze použít case prohlášení.

$ 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 

Odpovědět

Nejvíce náchylný k chybám, se kterými jsem mohl přijít, byl:

  • Nejprve získejte hodnotu. Předpokládejme něco jako:

RR=$?

Nyní nejen pro tuto situaci, ale i pro ostatní, kterým můžete čelit, zvažte:

definovaná proměnná:

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

Odpověď: ano

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

Odpověď: ne

nedefinovaná proměnná:

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

Odpověď: ne

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

Odpověď: ano

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

Odpověď: ano

Tím se zabrání chybám všech druhů.

Pravděpodobně jste si vědomi všech syntaxí, ale zde některé tipy:

  • Používejte uvozovky. Nepoužívejte "blank", který má být nothing.
  • Nová moderní notace pro proměnné je ${variable}.
  • Přidáním nuly zřetězené před vaše číslo se také vyhnete „vůbec žádnému číslu“.
  • Počkejte však, přidáním nuly se z čísla stane base-8. U čísel nad 7 se zobrazí chyba jako:
    • value too great for base (error token is "08"). Tehdy vstoupí do hry 10#:
    • 10# vynutí číslo base-10.

Odpověď

Můžete to udělat:

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

Komentáře

  • Funguje to, ale je to spletité. ‚ znovu spouštíte ping v subshellu subshellu, výstup ping je zachycen s ohledem na jeho spuštění jako příkazu. Ale protože výstup je přesměrován na / dev / null, bude to vždy prázdný řetězec. Takže ‚ znovu nespouštíte nic v subshellu, což znamená, že bude zachován předchozí stav ukončení (podsubstituly příkazu, to je ping). Správná cesta je samozřejmě if ping ...; then zde.

Odpověď

Jak je uvedeno jinde v tomto vlákně, původní otázka v podstatě odpovídá sama na sebe. Zde je ilustrace ukazující, že if podmínky mohou být také vnořené.

Tento příklad používá if ke kontrole, zda soubor existuje a zda se jedná o běžný soubor. Pokud jsou tyto podmínky pravdivé, zkontrolujte, zda má velikost větší než 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 

Komentáře

  • To je to, co dělá vaše odpověď, ale vaše odpověď otázku neřeší.
  • @JeffSchaller, děkuji za vaši poznámku. Upravil jsem svůj příspěvek tak, aby obsahoval odkaz na otázku.

Odpověď

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

Komentáře

Odpověď

Toho lze dosáhnout jednoduše tímto způsobem, protože $? vám dává status posledního provedeného příkazu.

Takže by to mohlo být

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

Komentáře

  • Downvote: Toto jednoduše parafrázuje dřívější odpověď, která oprávněně přijala kritiku za to, že je unidiomatická.
  • Ve skutečnosti to bylo přesně to, co jsem hledal, protože se ‚ snažím aby “ příkaz “ selhal ve skriptu jako součást “ set -e “ což však není ‚ t, pokud je ‚ součástí if.To by nemělo být ‚ odmítnuto.

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *