2010-03-05 21 views

Respuesta

38

StackOverflow no me permitirá eliminar mi respuesta ya que es la aceptada. Está obteniendo votos bajos ya que está en la parte superior de la lista con una mejor solución debajo. Si está en un sistema GNU, use timeout en su lugar, como lo sugiere @wRAR. Así, con la esperanza de que va a dejar de abajo a voto, así es como funciona:

timeout 1s ./myProgram 

Puede utilizar s, m, h o d de segundos (el valor por defecto si se omite), minutos, horas o días. Una característica interesante aquí es que puede especificar otra opción -k 30s (antes del 1s anterior) para matarla con un SIGKILL después de otros 30 segundos, en caso de que no responda al SIGTERM original.

Una herramienta muy útil. Ahora desplácese hacia abajo y hacia arriba, vote @ wRAR's answer.


Para la posteridad, esta fue mi sugerencia original - inferior, todavía podría ser si algunos usan para alguien.

Un simple golpe-escritura debe ser capaz de hacer eso para usted

./myProgram & 
sleep 1 
kill $! 2>/dev/null && echo "myProgram didn't finish" 

que debería hacerlo.

$! se expande hasta el último proceso de fondo (mediante el uso de &), y kill devuelve falso si no mató ningún proceso, por lo que el eco solo se ejecuta si realmente mató algo.

2>/dev/null redirige kill's stderr, de lo contrario se imprimirá algo que indique que no ha podido matar el proceso.

Es posible que desee agregar un -KILL o la señal que desee utilizar para deshacerse de su proceso también.

EDITAR
Como ephemient señaló, hay una carrera aquí si sus acabados del programa y el otro proceso arrebata el pid, se obtendrá mataron en su lugar. Para reducir la probabilidad de que suceda, podrías reaccionar al SIGCHLD y no intentar matarlo si eso sucede. Todavía hay posibilidad de matar el proceso incorrecto, pero es muy remoto.

trapped="" 
trap 'trapped=yes' SIGCHLD 
./myProgram & 
sleep 1 
[ -z "$trapped" ] && kill $! 2>/dev/null && echo '...' 
+0

Esto funcionó ... gracias – Overdeath

+1

Puede que desee guardar 'PID = $!', Establecer un 'trap' PID = 'SIGCHLD', y '[-n $ PID] && kill $ pid', de modo que en el (improbable) caso en que su hijo salga y se inicie otro proceso reutilizando el mismo PID, no mate al espectador inocente. – ephemient

+0

@ephemient: sí, lo consideré también. no eliminará la carrera por completo, pero ciertamente reducirá la ventana. – falstro

3

que podría lanzarlo en un script de shell utilizando &

your_program & 
pid=$! 
sleep 1 
if [ `pgrep $pid` ] 
    then 
    kill $pid 
    echo "killed $pid because it took too long." 
fi 

esperanza se entiende la idea, no estoy seguro de que esto es correcto mis conocimientos de shell necesitan un poco de actualización :)

0

Si tiene las fuentes, puede fork() temprano en main() y luego hacer que el proceso principal mida el tiempo y posiblemente mate el proceso secundario. Simplemente use las llamadas al sistema estándar fork(), waitpid(), kill(), ... tal vez algún manejo de señal Unix estándar. No es demasiado complicado, pero requiere un poco de esfuerzo.

También puede ejecutar un script en el shell aunque dudo que sea tan preciso con respecto al tiempo de 1 segundo.

Si solo quiere medir la hora, escriba time <cmd ...> en la carcasa.

+0

Esta era la forma en que pensé en hacerlo en el primer tiempo. Pero necesito que el programa funcione sin acceso a los archivos fuente. Gracias por la respuesta – Overdeath

18

¿Tal vez el límite de tiempo de la CPU (ulimit -t/setrlimit(RLIMIT_CPU)) ayudará?

+0

+1 para un enfoque genial! :) – falstro

+0

¿Cómo podría verificar si el programa excedió el tiempo de ejecución? – Overdeath

+0

@Overaath: Probablemente tendrías que hacer tu propio programa 'fork',' setrlimit' y 'waitpid', y luego comprobar si fue destruido por un SIGXCPU. También puede verificar el valor de retorno de su programa, bash generalmente establece '$?' En algo alto cuando es matado por una señal. No sé si es posible determinar si es SIGXCPU. – falstro

1

Ok, por lo que acaba de escribir un programa corto de C que fork s, llamadas execlp o algo similar en el niño, mide el tiempo en que el padre y el niño kill s. Debe ser fácil ...

88

Ah bien. timeout(1).

DESCRIPCIÓN
El comando de arranque, y matarlo si sigue corriendo tras DURACIÓN.

+1

Por favor, comenten sobre downvoting. – wRAR

+5

Creo que hubo un malentendido aquí. un simple "tiempo de espera para el hombre" puede mostrar que esta respuesta es la respuesta más precisa (aunque algo concisa) a la pregunta en cuestión. –

+4

timeout (1) está en GNU coreutils. – minopret

1
tail -f file & pid=$! 
sleep 10 
kill $pid 2>/dev/null && echo '...' 
Cuestiones relacionadas