Встроенный 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