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
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ýtnothing
. - 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 nad7
se zobrazí chyba jako:-
value too great for base (error token is "08")
. Tehdy vstoupí do hry10#
: -
10#
vynutí číslobase-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
- Vypadá to docela jako existující přijatá odpověď ; atribut pracujte s ‚ opětovným použitím nebo do svých odpovědí přidejte vlastní úsilí.
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.
then
vložit na samostatný řádek.if ! command ; then ... ; fi
.[
je sám o sobě příkaz a v tomto případě to ‚ není potřeba.if [ ! command ]
neprovádí ‚command
; považujecommand
za řetězec a zachází s ním jako s pravdou, protože má nenulovou délku.[
je synonymem pro příkaztest