Antworten:
Ein Ansatz wäre set -e
, am Anfang Ihres Skripts einzufügen. Das heißt (von help set
):
-e Exit immediately if a command exits with a non-zero status.
Wenn also einer Ihrer Befehle fehlschlägt, wird das Skript beendet.
Alternativ können Sie explizite exit
Anweisungen an den möglichen Fehlerpunkten hinzufügen :
command || exit 1
set -e
das weiß ich nur so.
set -e
werden sleep
(da break
es sich um ein spezielles Feature handelt, wird das Skript bei Fehlern in den meisten Shells beendet. Befehle in if
oder links davon &&
sind davon nicht betroffen set -e
, können n=...
jedoch fehlschlagen, wenn sie n
schreibgeschützt sind.) das würde das Skript auch ohne verlassen set -e
, so dass die Interpretation ziemlich unwahrscheinlich klingt. Ich bin damit einverstanden, dass die Frage schlecht formuliert ist.
Sie können ein Skript an einer beliebigen Stelle mit dem Schlüsselwort beenden exit
. Sie können auch einen Exit - Code angeben , um andere Programme , um anzuzeigen , dass oder wie Ihr Skript fehlgeschlagen ist , zB exit 1
oder exit 2
usw. (Vereinbarungs Exit - Code 0 ist für den Erfolg und etwas größer als 0 bedeutet Versagen, aber auch durch Konvention, Ausfahrt Codes über 127 sind für eine abnormale Beendigung reserviert (z. B. durch ein Signal).
Die generische Konstruktion, die bei einem Ausfall beendet werden soll, ist
if [ failure condition ]; then
exit n
fi
mit passendem failure condition
und n
. In bestimmten Szenarien können Sie jedoch anders vorgehen. Für Ihren Fall interpretiere ich Ihre Frage so, dass Sie den Vorgang beenden möchten, wenn einer der fünf gksu
fehlgeschlagenen Aufrufe fehlschlägt. Eine Möglichkeit besteht darin, eine solche Funktion zu verwenden
function try_command {
for i in 1 2 3 4 5 ; do
if gksu command ; then
return 0
fi
fi
exit 1
}
Rufen Sie dann die Schleife von auf try_command
.
Es gibt (fortgeschrittenere) oder ausgefeiltere Möglichkeiten, um Ihre Frage zu beantworten. Die obige Lösung ist jedoch für Anfänger zugänglicher als beispielsweise Stephanes Lösung.
attempt=0
until gksu command; do
attempt=$((attempt + 1))
if [ "$attempt" -gt 5 ]; then
exit 1
fi
done
exit
Beendet das Skript, sofern es nicht in einer Subshell aufgerufen wird. Befindet sich dieser Teil des Skripts in einer Subshell, z. B. weil er sich in (...)
oder innerhalb einer Pipeline befindet, $(...)
wird nur diese Subshell beendet .
Wenn Sie in diesem Fall möchten, dass das Skript zusätzlich zur Subshell beendet wird, müssen Sie exit
diese Subshell beenden.
Zum Beispiel hier mit 2 verschachtelten Ebenen von Subshells:
(
life=hard
output=$(
echo blah
[ "$life" = easy ] || exit 1 # exit subshell
echo blih not run
) || exit # if the subshell exits with a non-zero exit status,
# exit as well with the same exit status
echo not run either
) || exit # if the subshell exits with a non-zero exit status,
# exit as well with the same exit status
Es kann schwieriger werden, wenn die Subshell Teil einer Pipeline ist. bash
hat ein spezielles $PIPESTATUS
Array, ähnlich dem zsh
, $pipestatus
das Ihnen hier helfen kann:
{
echo foo
exit 1
echo bar
} | wc -c
subshell_ret=${PIPESTATUS[0]}
if [ "$subshell_ret" -ne 0 ]; then
exit "$subshell_ret"
fi
Die Falle führt beim Empfang eines Signals eine Aktion aus.
trap "echo EXIT; exit" 0
trap "echo HUP; exit" 1
trap "echo CTL-C; exit" 2
trap "echo QUIT; exit" 3
trap "echo ERR; exit" ERR
n=0
until [ $n -ge 5 ]
do
n=$[$n+1]
echo $n
sleep 3
done
Führen Sie dies aus und lassen Sie es normal beenden. Es wird auf Signal 0 abgefangen.
EXIT
Führen Sie es erneut aus und unterbrechen Sie mit ^ C. Es fängt sowohl das Signal 2 als auch das Signal 0 ab.
CTL-C
EXIT
Ein Ausgangsstatus ungleich Null wird bei ERR abgefangen
ERR
EXIT
set -e
-Funktion zu verwenden. Hier trifft es allerdings nicht wirklich zu. Das OP möchte das Skript nach 5 fehlgeschlagenen Versuchen, den Befehl auszuführen, beenden.