Есть (как минимум) две программы, которые предоставляют эту функциональность:
ИМЯ
timelimit
- эффективно ограничивать абсолютное время выполнения процесса
СИНТАКСИС
timelimit [-pq] [-S killsig] [-s warnsig] [-T killtime] [-t warntime] command [arguments ...]
а также
ИМЯ
timeout
- запустить команду с ограничением по времени
СИНТАКСИС
timeout [OPTION] DURATION COMMAND [ARG]...
timeout [OPTION]
Они упакованы следующим образом:
$ dlocate `which timeout timelimit`
timelimit: /usr/bin/timelimit
coreutils: /usr/bin/timeout
Сравнение:
/-----------------------------+------------+----------------\
| Feature | timelimit | timeout |
+=============================+============+================+
| time to run | -t time | first argument |
+-----------------------------+------------+----------------+
| terminate signal | -s signal | -s signal |
+-----------------------------+------------+----------------+
| grace period | -T time | -k time |
+-----------------------------+------------+----------------+
| kill signal | -S signal | (note 1) |
+-----------------------------+------------+----------------+
| propagate signals | -p | (note 2) |
\-----------------------------+------------+----------------/
Примечания:
timeout
всегда использует в SIGKILL
качестве последнего средства.
timeout
не имеет никакой функциональности для выхода с сигналом, когда это делает дочерняя программа.
Состояние выхода этих двух программ различается, но сложно аккуратно подвести итог, поэтому я советую вам самим обратиться к справочным страницам.
Так timeout
как по умолчанию устанавливается на большее количество систем ( coreutils
это стандартный пакет во многих дистрибутивах), я предлагаю вам использовать его, если вам не нужны дополнительные функции, предоставляемые timelimit
.
timelimit
. Смотрите Как я могу завершить процесс и быть уверенным, что PID не был повторно использован для получения дополнительной информации о них и времени ожидания GNU.timeout
включен в GNU coreutils ,timelimit
но не включен . Вы можете установить ни один, один или оба. Для второго сообщается, что ограничение по времени выполняет команду и завершает порожденный процесс через заданное время с данным сигналом. Сначала отправляется сигнал «предупреждение» , затем, после тайм-аута, сигнал «убить», аналогично тому, как init (8) работает при выключении. Так что даже в середине другое поведение.timeout
это путь туда.На самом деле, это то, что
timeout
для:источник
Чистый
bash
встроенный, без coreutilsЯ обнаружил, что это решение работает
bash
на основе встроенной команды без вызова внешнего исполняемого файла. Он работает в системе, где в конце концов даже не были установлены coreutils [ 1 ]Пояснения : как обычно при отправке команды в фоновом режиме с
&
его PID хранится во внутренней переменной$!
(присутствующее в современной версииdash
,csh
,bash
,tcsh
,zsh
...).Что действительно отличает оболочку, так это наличие встроенной команды
read
[ 2 ] и опции-t
. В 1-й версии, если пользователь не завершит строку ввода до указанного количества секунд, инструкция будет прервана и будет сгенерирован код возврата ошибки.Вторая версия работает как первая, но вы можете отменить тайм-аут убийства, просто нажав enter.
Действительно, оператор or
||
выполняетkill
оператор только в том случае, еслиread
команда завершается с кодом возврата, отличным от нуля, как по истечении времени ожидания. Если вы нажмете enterдо этого момента, он вернет 0 и не убьет вашу предыдущую команду.Решения Coreutils [ 1 ]
Когда в вашей системе присутствуют coreutils , и вам не нужно экономить время и ресурсы для вызова внешней программы,
timeout
иsleep
оба они являются идеальными способами достижения вашей цели.timeout
Использованиеtimeout
просто.В конце концов, вы можете использовать
-k
опцию для отправки дополнительного сигнала уничтожения, если первый сбой.sleep
С помощьюsleep
вы можете использовать свою фантазию или взять некоторые вдохновения [ 3 ] . Обратите внимание, что вы можете оставить свою команду в фоновом режиме или на переднем плане (например,top
обычно должен быть на переднем плане).Пояснения
YourCommand
затем ваши оболочкиsleep
на 5 минут. Когда он будет закончен, последний фоновый процесс ($!
) будет убит. Вы останавливаете свою раковину.YourCommand
и немедленно сохраняете этот PID в переменной$pid
. Затем вы выполняете в фоновом режиме дремоту 5 минут и последующую команду, которая уничтожит этот сохраненный PID. Поскольку вы отправили эту группу команд в фоновом режиме, вы не остановите свою оболочку. Вам необходимо сохранить PID в переменной, так как значение$!
может быть обновлено путем возможного выполнения другой программы в фоновом режиме. Проще говоря, вы избегаете риска убить неправильный процесс или вообще ни одного процесса.$$
, затем выполняется ваша команда, которая остается на переднем плане.()
которая сохраняет свой PID в переменной (cmdpid
) и убивает себя другой подоболочкой, отправляемой в фоновом режиме, а затем запускает YourCommand на переднем плане.Конечно, в каждой версии вы можете посылать необходимый вам сигнал уничтожения, от стандартного до крайнего
kill -9
, который будет использоваться только тогда, когда это действительно необходимо.Рекомендации
источник
Для вашего конкретного случая большинство реализаций
ping
поддержки-c
или--count
прекращения после определенного количества пингов:Для более общего решения см. Другие ответы.
источник
ping
конкретный пример. Он не хочет индивидуального решения для каждой отдельной программы.Вы можете сделать это с помощью простого скрипта:
(сигнал SIGINT = 2 используется в соответствии с предложением Матии Налис в комментарии ниже).
Объяснение (необычного?) Выражения bash
$@:...
: позиционные параметры, ($*, $@, "$*", "$@"
) допускают следующую дополнительную спецификацию, например:что означает: из всех параметров возьмите COUNT из них, первым из которых будет значение, которое находится в положении STARTth; если COUNT опущен, возьмите их все до конца, начиная с позиции STARTth. Помните, что
$0
это имя программы. Если START отрицателен, начните отсчет с конца и помните, что COUNT не может быть отрицательным, поэтому последний аргумент - это"${@:-1}"
. Кроме того, почти всегда включайте позиционные параметры в двойные кавычки.источник
$1
довольно грубо. Кроме того, вы можете простоsleep "$1"
или что-то вcountdown
.time=$1; shift
, а затем вам не нужен синтаксис разбиения массива для позиционных параметров. Но да, это намного проще.ctrl-c
, лучше попробоватьkill -INT
вместоkill -9
(или, по крайней мере, попытаться-9
только через несколько секунд, если первая не удалась - это дает программе возможность чисто завершиться и не оставлять временные файлы). и т.д. вокруг)Так как вы упоминаете
ping
в своем примере; эта команда имеет несколько опций для остановки через определенное время:источник