Встроенный Pure bash
, без Coreutils
Я обнаружил, что это решение работает в bash
опираясь на встроенную команду без вызова внешнего исполняемого файла. Он работает в системе, где в конце концов даже не были установлены coreutils [ 1 ]
YourCommand & read -t 300 ; kill $! # 1st version
YourCommand & read -t 300 || kill $! # 2nd version
Пояснения: как обычно, когда вы отправляете команду в фоновом режиме с &
, ее PID сохраняется во внутренней переменной $!
(присутствует в современной версии dash
, csh
, bash
, tcsh
, zsh
...).
Разница между оболочками действительно заключается в наличии встроенной команды read
[ 2 ] и опции -t
.
В 1-й версии, если пользователь не завершит строку ввода до указанного количества секунд, инструкция будет прервана и будет сгенерирован код возврата ошибки.
-t TIMEOUT Вызывает чтение до истечения времени ожидания и возвращает ошибку, если полная строка ввода не считывается в течение TIMEOUT секунд.
Вторая версия работает как первая, но вы можете прервать тайм-аут, просто нажав Enter.
Действительно оператор или ||
выполняет оператор kill
только в том случае, если команда read
завершается с кодом возврата, отличным от нуля, как по истечении времени ожидания. Если вы нажмете ввод до этого момента, он вернет 0 и не убьет вашу предыдущую команду.
Решения Coreutils [ 1 ]
Если в вашей системе присутствуют coreutils , и вам не нужно экономить время и ресурсы для вызова внешней программы, timeout
и sleep
- это идеальный способ достичь своей цели.
timeout
Использование timeout
просто.
В конце концов, вы можете использовать опцию -k
для отправки дополнительного сигнала уничтожения, если первый сбой.
timeout 5m YourCommand # 3rd version
sleep
Со sleep
вы можете использовать свою фантазию или вдохновение [ 3 ]. Обратите внимание, что вы можете оставить свою команду в фоновом режиме или на переднем плане (например, top
обычно должен быть на переднем плане).
YourCommand & sleep 5m; kill $! # 4th Background
YourCommand & pid=$! ; (sleep 5m; kill $pid;) & # 5th Background
bash -c '(sleep 5m; kill $$) & exec YourCommand' # 6th Foreground
(cmdpid=$BASHPID; (sleep 5m; kill $cmdpid) & exec YourCommand) # 7th Foreground
Пояснения
- В 4-й версии вы выполняете в фоновом режиме
YourCommand
затем ваша оболочка sleep
течение 5 минут. Когда будет закончен последний фоновый процесс ($!
) будет убит. Вы останавливаете свою раковину.
-
В 5-й версии вместо этого вы выполняете в фоновом режиме
YourCommand
и немедленно сохраняете этот PID в переменной $pid
. Затем вы выполняете в фоновом режиме дремоту 5 минут и последующую команду, которая уничтожит этот сохраненный PID. Так как вы отправили эту группу команд в фоновом режиме, вы не остановите свою оболочку. Вам нужно хранить PID в переменной, потому что значение $!
может быть обновлено путем возможного выполнения другой программы в фоновом режиме. Проще говоря, вы избегаете риска убить неправильный процесс или вообще ни одного процесса.
- В 6-й версии это называется новой оболочкой bash, которая самоубийство самоубийства через 5 минут через
$$
, затем выполняется ваша команда, которая остается на переднем плане.
- В 7-й версии он вызывается subshell
()
который сохраняет свой PID в переменной (cmdpid
) и убивает себя с помощью другого subshell, отправленного в фоновом режиме, а затем запускает YourCommand на переднем плане.
Конечно, в каждой версии вы можете посылать необходимый сигнал уничтожения, от стандартного до экстремального kill -9
, который будет использоваться только тогда, когда это действительно необходимо.
Рекомендации
- [ 1 ] Coreutils
- [ 2 ] Руководство для начинающих Bash
- [ 3 ] BASFAQ