Відповіді:
Одним із підходів було б додати 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т.д. коди вище 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«и $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 невдалих спроб запуску команди.