Hay (al menos) dos programas que proporcionan esta funcionalidad:
NOMBRE
timelimit
- limitar efectivamente el tiempo de ejecución absoluto de un proceso
SINOPSIS
timelimit [-pq] [-S killsig] [-s warnsig] [-T killtime] [-t warntime] command [arguments ...]
y
NOMBRE
timeout
- ejecutar un comando con un límite de tiempo
SINOPSIS
timeout [OPTION] DURATION COMMAND [ARG]...
timeout [OPTION]
Se empaquetan de la siguiente manera:
$ dlocate `which timeout timelimit`
timelimit: /usr/bin/timelimit
coreutils: /usr/bin/timeout
Comparación:
/-----------------------------+------------+----------------\
| 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) |
\-----------------------------+------------+----------------/
Notas:
timeout
siempre se usa SIGKILL
como señal de último recurso.
timeout
no tiene ninguna funcionalidad para salir con una señal cuando el programa secundario lo hace.
El estado de salida de los dos programas difiere, pero eso es difícil de resumir claramente, por lo que le sugiero que consulte las páginas del manual.
Como timeout
está instalado en más sistemas de manera predeterminada ( coreutils
es un paquete estándar en muchas distribuciones), le sugiero que lo use a menos que necesite la funcionalidad adicional proporcionada por timelimit
.
timelimit
. Consulte Cómo puedo eliminar un proceso y asegúrese de que el PID no se haya reutilizado para obtener más información sobre ellos y el tiempo de espera de GNU.timeout
está incluido en GNU coreutils ,timelimit
no lo está. Puede haber instalado ninguno, uno o ambos. Para el segundo, se informa que timelimit ejecuta un comando y finaliza el proceso generado después de un tiempo determinado con una señal dada. Primero se envía una señal de "advertencia" , luego, después de un tiempo de espera, una señal de "muerte", similar a la forma en que init (8) opera en el apagado. Entonces, incluso un comportamiento diferente en el medio .timeout
es el camino a seguir.En realidad, esto es para lo que
timeout
sirve:fuente
Puro
bash
incorporado, sin coreutilsDescubrí 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 ]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 dedash
,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.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 lakill
instrucción solo si elread
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
ysleep
ambas son formas perfectas de alcanzar su objetivo.timeout
El uso detimeout
es sencillo.Eventualmente, puede considerar usar también la
-k
opción de enviar una señal de muerte adicional si la primera falla.sleep
Consleep
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).Explicaciones
YourCommand
luego su shellsleep
es de 5 minutos. Cuando finalice, el último proceso en segundo plano ($!
) se eliminará. Tú detienes tu caparazón.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.$$
, luego se ejecuta su comando que permanece en primer plano.()
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
fuente
Para su caso particular, la mayoría de las implementaciones de
ping
soporte-c
o--count
para finalizar después de un número particular de pings:Para una solución más general, vea las otras respuestas.
fuente
ping
un ejemplo concreto. No quiere una solución caso por caso para cada programa diferente.Puedes hacerlo con un script simple como este:
(señal SIGINT = 2 utilizada según la sugerencia de Matija Nalis en el comentario a continuación).
Una explicación de la expresión bash (¿poco común?)
$@:...
: Los parámetros posicionales, ($*, $@, "$*", "$@"
) admiten la siguiente especificación adicional, por ejemplo:lo que significa: de todos los parámetros, tomar COUNT de ellos, el primero en ser tomado es el de la posición START; Si se omite COUNT, llévelos todos hasta el final, comenzando con la posición STARTth. Recuerde que ese
$0
es el nombre del programa. Si START es negativo, comience a contar desde el final y recuerde que COUNT no puede ser negativo, por lo tanto, el último argumento es"${@:-1}"
. Además, casi siempre incluye los parámetros posicionales dentro de las comillas dobles.fuente
$1
es bastante asqueroso. Además, podrías simplementesleep "$1"
o algo asícountdown
.time=$1; shift
, y luego no necesita la sintaxis de corte de matriz para los parámetros posicionales. Pero sí, eso es mucho más simple.ctrl-c
, probablemente sea mejor intentarlo enkill -INT
lugar dekill -9
(o al menos intentarlo-9
solo después de unos segundos si el primero no tuvo éxito; le da al programa la oportunidad de salir limpiamente y no dejar archivos temporales etc alrededor)Como mencionas
ping
en tu ejemplo; Este comando tiene algunas opciones para detenerse después de un período de tiempo específico:fuente