У меня есть команда, которую я хочу автоматически запускать каждый раз после ее завершения, поэтому я выполнил что-то вроде этого:
while [ 1 ]; do COMMAND; done;
но если я не могу остановить цикл с помощью Ctrl-cas, то это просто убивает COMMAND
, а не весь цикл.
Как мне добиться чего-то подобного, но при этом остановить это, не закрывая терминал?
решение1
Вы можете остановить и перевести свою задачу в фоновый режим, пока она выполняется, используя ctrl+ z. Затем вы можете завершить свою задачу с помощью:
$ kill %1
Где [1] — номер вашей работы.
решение2
Проверьте статус выхода команды. Если команда была завершена сигналом, код выхода будет 128 + номер сигнала. ИзОнлайн-документация GNU для bash:
Для целей оболочки команда, которая завершается с нулевым статусом выхода, считается успешно выполненной. Ненулевой статус выхода указывает на сбой. Эта, казалось бы, нелогичная схема используется, поэтому существует один четко определенный способ указать на успех и множество способов указать на различные режимы сбоя. Когда команда завершается фатальным сигналом с номером N, Bash использует значение 128+N в качестве статуса выхода.
POSIX также определяетчто значение команды, завершённой сигналом, больше 128, но, похоже, не указывает его точное значение, как это делает GNU:
Статус завершения команды, выполнение которой было прекращено из-за получения сигнала, должен быть указан как больший, чем 128.
Например, если вы прерываете команду с помощью control-C, код выхода будет 130, поскольку SIGINT — это сигнал 2 в системах Unix. Итак:
while [ 1 ]; do COMMAND; test $? -gt 128 && break; done
решение3
Я бы сказал, что лучше всего поместить бесконечный цикл в скрипт и обрабатывать сигналы там. ВотОсновная отправная точка. Я уверен, что вы захотите изменить его под себя. Скрипт использует trap
для перехвата ctrl- c(или SIGTERM
), убивает команду (я использовал sleep
здесь в качестве теста) и завершается.
cleanup ()
{
kill -s SIGTERM $!
exit 0
}
trap cleanup SIGINT SIGTERM
while [ 1 ]
do
sleep 60 &
wait $!
done
решение4
Если вы запустите bash, -e
он завершит работу при возникновении любых ошибок:
#!/bin/bash -e
false # returns 1
echo This won't be printed