Ответы:
Одним из подходов будет добавление 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 неудачных попыток выполнить команду.