Puro bash
incorporado, sin coreutils
Descubrí que esta solución funciona al bash
confiar en un comando incorporado sin llamar a un ejecutable externo. Funciona en sistemas donde eventualmente ni siquiera se han instalado los coreutils [ 1 ]
YourCommand & read -t 300 ; kill $! # 1st version
YourCommand & read -t 300 || kill $! # 2nd version
Explicaciones : como de costumbre cuando se envía un comando en el fondo con &
, su PID se almacena en la variable interna $!
(presente en la versión moderna de dash
, csh
, bash
, tcsh
, zsh
...).
Lo que realmente marca la diferencia entre los shells es la presencia del comando incorporado read
[ 2 ] y de la opción -t
. En la primera versión, si el usuario no completará una línea de entrada antes de la cantidad de segundos especificada, la instrucción finalizará y se generará un código de retorno de error.
-t TIEMPO DE ESPERA Causa la lectura del tiempo de espera y devuelve el fallo si no se lee una línea completa de entrada en segundos de TIEMPO DE ESPERA.
La segunda versión funciona como la primera, pero puede abortar el tiempo de espera de matar simplemente presionando enter.
De hecho, el operador o ||
ejecuta la kill
instrucción solo si el read
comando sale con un código de retorno diferente de cero, como cuando expira el tiempo de espera. Si presiona enterantes de ese momento, devolverá 0 y no matará su comando anterior.
Soluciones Coreutils [ 1 ]
Cuando coreutils está presente en su sistema y no tiene necesidad de ahorrar tiempo y recursos para llamar a un programa externo, timeout
y sleep
ambas son formas perfectas de alcanzar su objetivo.
timeout
El uso de timeout
es sencillo.
Eventualmente, puede considerar usar también la -k
opción de enviar una señal de muerte adicional si la primera falla.
timeout 5m YourCommand # 3rd version
sleep
Con sleep
usted puede usar su fantasía o tomar algunas inspiraciones [ 3 ] . Tenga en cuenta que puede dejar su comando en segundo plano o en primer plano (por ejemplo, top
generalmente debe estar en primer plano).
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
Explicaciones
- En la cuarta versión, ejecuta en segundo plano y
YourCommand
luego su shell sleep
es de 5 minutos. Cuando finalice, el último proceso en segundo plano ( $!
) se eliminará. Tú detienes tu caparazón.
-
En la quinta versión, en su lugar, ejecuta en segundo plano
YourCommand
y almacena inmediatamente ese PID en la variable $pid
. Luego ejecutas en segundo plano una siesta de 5 minutos y su consecuente comando que matará ese PID almacenado. Como envió este grupo de comandos en segundo plano, no detiene su shell. Necesita almacenar el PID en una variable porque el valor de $!
se puede actualizar mediante una ejecución eventual de otro programa en segundo plano. En palabras simples, evitas el riesgo de matar el proceso incorrecto o ningún proceso en absoluto.
- En la sexta versión se llama un nuevo shell de bash que se suicidará en 5 minutos
$$
, luego se ejecuta su comando que permanece en primer plano.
- En la séptima versión se invoca una subshell
()
que almacena su PID en una variable ( cmdpid
) y se suicida con otra subshell enviada en ejecución en segundo plano, luego ejecuta YourCommand en primer plano.
Por supuesto, en cada versión puede enviar la señal de apagado que necesita, desde la predeterminada hasta el extremo kill -9
, para usarla solo cuando realmente la necesite.
Referencias
- [ 1 ] Los Coreutils
- [ 2 ] La guía para principiantes de Bash
- [ 3 ] El BashFAQ