Чистый 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.
Действительно, оператор or ||
выполняет kill
оператор только в том случае, если read
команда завершается с кодом возврата, отличным от нуля, как по истечении времени ожидания. Если вы нажмете enterдо этого момента, он вернет 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-й версии он вызывает подоболочку,
()
которая сохраняет свой PID в переменной ( cmdpid
) и убивает себя другой подоболочкой, отправляемой в фоновом режиме, а затем запускает YourCommand на переднем плане.
Конечно, в каждой версии вы можете посылать необходимый вам сигнал уничтожения, от стандартного до крайнего kill -9
, который будет использоваться только тогда, когда это действительно необходимо.
Рекомендации
- [ 1 ] Coreutils
- [ 2 ] Руководство для начинающих Bash
- [ 3 ] BASFAQ