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 exitAnweisungen an den möglichen Fehlerpunkten hinzufügen :
command || exit 1
set -edas weiß ich nur so.
set -ewerden sleep(da breakes sich um ein spezielles Feature handelt, wird das Skript bei Fehlern in den meisten Shells beendet. Befehle in ifoder links davon &&sind davon nicht betroffen set -e, können n=...jedoch fehlschlagen, wenn sie nschreibgeschü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 1oder exit 2usw. (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 conditionund 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 gksufehlgeschlagenen 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
exitBeendet 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 exitdiese 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. bashhat ein spezielles $PIPESTATUSArray, ähnlich dem zsh, $pipestatusdas 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.