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:
timeoutsiempre se usa SIGKILLcomo 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 timeoutestá instalado en más sistemas de manera predeterminada ( coreutilses 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.timeoutestá incluido en GNU coreutils ,timelimitno 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 .timeoutes el camino a seguir.En realidad, esto es para lo que
timeoutsirve:fuente
Puro
bashincorporado, sin coreutilsDescubrí que esta solución funciona al
bashconfiar 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 lakillinstrucción solo si elreadcomando 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,
timeoutysleepambas son formas perfectas de alcanzar su objetivo.timeoutEl uso detimeoutes sencillo.Eventualmente, puede considerar usar también la
-kopción de enviar una señal de muerte adicional si la primera falla.sleepConsleepusted 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,topgeneralmente debe estar en primer plano).Explicaciones
YourCommandluego su shellsleepes de 5 minutos. Cuando finalice, el último proceso en segundo plano ($!) se eliminará. Tú detienes tu caparazón.YourCommandy 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
pingsoporte-co--countpara finalizar después de un número particular de pings:Para una solución más general, vea las otras respuestas.
fuente
pingun 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
$0es 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
$1es 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 -INTlugar dekill -9(o al menos intentarlo-9solo 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
pingen tu ejemplo; Este comando tiene algunas opciones para detenerse después de un período de tiempo específico:fuente