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