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 if
robi 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.]
[
test
if
if
Edycja: zacytowałem pytanie u góry dla jasności (ta odpowiedź nie pojawia się u góry strony).
then
w osobnej linii.
if ! command ; then ... ; fi
. [
sam w sobie jest poleceniem i w tym przypadku nie jest potrzebny.
if [ ! command ]
nie wykonuje command
; traktuje command
jak ciąg i traktuje to jako prawdziwe, ponieważ ma niezerową długość. [
jest synonimem test
polecenia
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
if
idiomu Basha . Wolę odpowiedź Keitha Thompsona.
if
jest 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 ! cmd
jest w porządku. W przeciwnym razie powszechnym rozwiązaniem jest użycie else
klauzuli. Nie możesz mieć pustego, then
ale czasami widzisz, then : nothing; else
gdzie :
brak op jest znaczący. true
też by tam działał.
To działało dla mnie:
command && echo "OK" || echo "NOK"
jeśli się command
powiedzie, 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...fi
i &&
/ 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 if
i &&
/ ||
podejścia nie będą działać dla tych konkretnych poleceń.
Na przykład w systemie Linux GNU file
nadal wychodzi z 0, jeśli otrzymał nieistniejący plik jako argument i find
nie 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
/ stdin
komunikaty, np. Te, które zwróciły file
polecenie lub parsują dane wyjściowe polecenia jak w find
. W tym celu case
moż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
ping
są 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 ...; then
tutaj.
Jak zauważono w innym miejscu tego wątku, pierwotne pytanie w zasadzie odpowiada samo. Oto ilustracja pokazująca, że if
warunki mogą być również zagnieżdżone.
W tym przykładzie użyto if
do 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