Ответы:
Одним из подходов будет добавление set -eв начало вашего сценария. Это значит (с help set):
-e Exit immediately if a command exits with a non-zero status.
Таким образом, если какая-либо из ваших команд завершится неудачно, скрипт завершится.
В качестве альтернативы, вы можете добавить явные exitоператоры в возможных точках отказа:
command || exit 1
set -eэто единственный способ, который я знаю, чтобы сделать это.
set -eэто sleep( breakбудучи специальной встроенной команды вызовет сценарий выхода на неудачу в большинстве оболочек, команд ifили слева от &&не влияет set -e, n=...может потерпеть неудачу , если nэто только для чтения, но потом это также вышло бы из сценария set -e), так что интерпретация кажется маловероятной. Я согласен, что вопрос плохо сформулирован.
Вы можете выйти из скрипта в любом месте, используя ключевое слово exit. Вы также можете указать код завершения, чтобы указать другим программам, что или как ваш сценарий вышел из строя, например, exit 1и exit 2т. Д. (Условно, код завершения 0 предназначен для успеха, а все, что больше 0, означает сбой; однако, также по соглашению, выход коды выше 127 зарезервированы для аварийного завершения (например, по сигналу)).
Общая конструкция для выхода из строя
if [ failure condition ]; then
exit n
fi
с подходящими failure conditionи n. Но в определенных сценариях вы можете действовать иначе. Теперь для вашего случая я интерпретирую ваш вопрос, что если какой-либо из пяти вызовов gksuпотерпел неудачу, то вы собираетесь выйти. Одним из способов является использование такой функции
function try_command {
for i in 1 2 3 4 5 ; do
if gksu command ; then
return 0
fi
fi
exit 1
}
а затем вызвать цикл с помощью try_command.
Существуют (более) продвинутые или сложные способы решения вашего вопроса. Однако приведенное выше решение более доступно для начинающих, чем, скажем, решение Стефана.
attempt=0
until gksu command; do
attempt=$((attempt + 1))
if [ "$attempt" -gt 5 ]; then
exit 1
fi
done
exitвыходит из сценария, если он не вызывается в подоболочке. Если эта часть скрипта в субоболочке, например , потому что это в пределах (...)или $(...)или части трубы линии, то это будет только выйти из этого подоболочки .
В этом случае, если вы хотите, чтобы скрипт завершал работу в дополнение к подоболочке, вам нужно будет вызвать exitвыход из этой подоболочки.
Например, здесь с 2 вложенными уровнями подоболочек:
(
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
Это может стать сложнее, если подоболочка является частью конвейера. bashимеет специальный $PIPESTATUSмассив, похожий на zsh«s $pipestatusодин , который может помочь вам здесь:
{
echo foo
exit 1
echo bar
} | wc -c
subshell_ret=${PIPESTATUS[0]}
if [ "$subshell_ret" -ne 0 ]; then
exit "$subshell_ret"
fi
Ловушка выполнит действие при получении сигнала.
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
Запустите это и дайте ему выйти нормально. Ловит сигнал 0.
EXIT
Запустите его снова и прервите с помощью ^ C. Он захватывает как сигнал 2, так и сигнал 0.
CTL-C
EXIT
Ненулевой статус выхода будет ловушкой ERR
ERR
EXIT
set -eфункции. Это действительно не применимо здесь, хотя. ОП хочет выйти из сценария после 5 неудачных попыток выполнить команду.