Jak mogę zrobić coś takiego w bash?
if "`command` returns any error";
then
echo "Returned an error"
else
echo "Proceed..."
fi
Jak mogę zrobić coś takiego w bash?
if "`command` returns any error";
then
echo "Returned an error"
else
echo "Proceed..."
fi
Odpowiedzi:
Jak warunkowo zrobić coś, jeśli polecenie zakończyło się powodzeniem lub niepowodzeniem
Właśnie to ifrobi oświadczenie bash :
if command ; then
echo "Command succeeded"
else
echo "Command failed"
fi
Dodawanie informacji z komentarzy: w tym przypadku nie musisz używać składni [... sam w sobie jest poleceniem, prawie równoważnym z . Jest to prawdopodobnie najczęstsze polecenie używane w komendzie , co może prowadzić do założenia, że jest to część składni powłoki. Ale jeśli chcesz sprawdzić, czy polecenie zakończyło się powodzeniem, użyj samego polecenia bezpośrednio , jak pokazano powyżej.][testifif
Edycja: zacytowałem pytanie u góry dla jasności (ta odpowiedź nie pojawia się u góry strony).
thenw osobnej linii.
if ! command ; then ... ; fi. [sam w sobie jest poleceniem i w tym przypadku nie jest potrzebny.
if [ ! command ]nie wykonuje command; traktuje commandjak ciąg i traktuje to jako prawdziwe, ponieważ ma niezerową długość. [jest synonimem testpolecenia
W przypadku drobnych rzeczy, które mają się zdarzyć, jeśli polecenie powłoki działa, możesz użyć &&konstrukcji:
rm -rf somedir && trace_output "Removed the directory"
Podobnie w przypadku drobnych rzeczy, które mają się zdarzyć, gdy polecenie powłoki nie powiedzie się, możesz użyć ||:
rm -rf somedir || exit_on_error "Failed to remove the directory"
Lub obydwa
rm -rf somedir && trace_output "Removed the directory" || exit_on_error "Failed to remove the directory"
Prawdopodobnie nierozsądnie jest robić wiele z tymi konstruktami, ale czasami mogą sprawić, że przepływ kontroli będzie znacznie wyraźniejszy.
Sprawdź wartość $?, która zawiera wynik wykonania ostatniego polecenia / funkcji:
#!/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
ifidiomu Basha . Wolę odpowiedź Keitha Thompsona.
ifjest to zrobić. Warunki kontroli przepływu w Bash sprawdzają się $?za kulisami; właśnie to robią. Jawne badanie jego wartości powinno być niepotrzebne w zdecydowanej większości przypadków i zwykle stanowi dla początkującego przeciwnika.
if ! cmdjest w porządku. W przeciwnym razie powszechnym rozwiązaniem jest użycie elseklauzuli. Nie możesz mieć pustego, thenale czasami widzisz, then : nothing; elsegdzie :brak op jest znaczący. trueteż by tam działał.
To działało dla mnie:
command && echo "OK" || echo "NOK"
jeśli się commandpowiedzie, echo "OK"zostanie wykonany, a ponieważ się powiedzie, wykonanie się tam kończy. W przeciwnym razie &&jest pomijany i echo "NOK"wykonywany.
command && echo "OK" || c=$?; echo "NOK"; $(exit $c)
command && echo "OK" || (c=$?; echo "NOK"; (exit $c))?
echo "OK"część sama mogłaby zawieść, to lepiej:command && (echo "OK"; exit 0) || (c=$?; echo "NOK"; (exit $c))
Należy zauważyć, że if...then...fii &&/ lub ||typ podejścia dotyczy statusu wyjścia zwracanego przez polecenie, które chcemy przetestować (0 w przypadku powodzenia); jednak niektóre polecenia nie zwracają niezerowego statusu wyjścia, jeśli polecenie zakończyło się niepowodzeniem lub nie mogło poradzić sobie z danymi wejściowymi. Oznacza to, że zwykłe ifi &&/ ||podejścia nie będą działać dla tych konkretnych poleceń.
Na przykład w systemie Linux GNU filenadal wychodzi z 0, jeśli otrzymał nieistniejący plik jako argument i findnie mógł zlokalizować określonego pliku użytkownika.
$ 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
W takich przypadkach jednym potencjalnym sposobem na poradzenie sobie z sytuacją jest odczyt stderr/ stdinkomunikaty, np. Te, które zwróciły filepolecenie lub parsują dane wyjściowe polecenia jak w find. W tym celu casemożna użyć instrukcji.
$ 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
Najbardziej podatny na błędy, jaki mogłem wymyślić, to:
RR=$?
Teraz, nie tylko dla tej sytuacji, ale dla innych, z którymi możesz się spotkać, rozważ:
$ AA=1 ; if (( "10#0${AA}" == 1 )) ; then echo yes ; else echo no ; fi
Odpowiedź: tak
$ AA=1 ; if (( "10#0${AA}" != 1 )) ; then echo yes ; else echo no ; fi
Odpowiedź: nie
$ AA=1 ; if (( "10#0${BB}" == 1 )) ; then echo yes ; else echo no ; fi
Odpowiedź: nie
$ AA=1 ; if (( "10#0${BB}" != 1 )) ; then echo yes ; else echo no ; fi
Odpowiedź: tak
$ AA=1 ; if (( "10#0${BB}" == 0 )) ; then echo yes ; else echo no ; fi
Odpowiedź: tak
Zapobiega to wszelkiego rodzaju błędom.
Prawdopodobnie znasz całą składnię, ale oto kilka wskazówek:
"blank"być nothing.${variable}.base-8. Pojawi się błąd, taki jak:
value too great for base (error token is "08")dla liczb powyżej 7. Właśnie wtedy 10#wchodzi w grę:10#wymusza, aby liczba była base-10.Możesz to zrobić:
if ($( ping 4.4.4.4 -c1 > /dev/null )) ; then
echo "ping response succsess!!!"
fi
pingsą przechwytywane w celu uruchomienia jako polecenia. Ale ponieważ dane wyjściowe są przekierowywane do / dev / null, który zawsze będzie pustym ciągiem. Więc nic nie uruchamiasz w podpowłoce, co oznacza, że poprzedni status wyjścia (podpowłoki zastępowania poleceń, czyli ping) zostanie zachowany. Oczywiście poprawna droga jest if ping ...; thentutaj.
Jak zauważono w innym miejscu tego wątku, pierwotne pytanie w zasadzie odpowiada samo. Oto ilustracja pokazująca, że ifwarunki mogą być również zagnieżdżone.
W tym przykładzie użyto ifdo sprawdzenia, czy plik istnieje i czy jest to zwykły plik. Jeśli te warunki są spełnione, sprawdź, czy ma rozmiar większy niż 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
#!/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
Można to zrobić po prostu w ten sposób, ponieważ $?daje status ostatniego wykonanego polecenia.
Tak może być
#!/bin/sh
... some command ...
if [ $? == 0 ] ; then
echo '<the output message you want to display>'
else
echo '<failure message>'
fi