Tuez un processus s'il se calme pendant un certain temps

9

J'ai un utilitaire qui a la méchante habitude de se taire et de rester là-bas, je sais déjà combien de temps il fait cela, donc j'utilise timeoutpour lutter contre cela, mais parfois il le fait avant cette date. Existe-t-il un outil similaire timeoutqui va tuer le processus s'il cesse de diriger la sortie vers stdout?

Benjojo
la source

Réponses:

8

Avec zsh, vous pourriez faire:

zmodload zsh/system
coproc your-command
while :; do
  sysread -t 10 -o 1 <&p && continue
  if (( $? == 4 )); then
    echo "Timeout" >&2
    kill $!
  fi
  break
done

L'idée étant d'utiliser l' -toption de sysreadlire depuis la your-commandsortie avec un timeout.

Notez qu'il fait de your-commandla sortie un tube. Il se peut que cela your-commandcommence à mettre en mémoire tampon sa sortie quand il ne va pas à un terminal, auquel cas vous pouvez constater qu'il ne sort rien quoi que ce soit dans un certain temps, mais uniquement à cause de cette mise en mémoire tampon, pas parce qu'il est suspendu d'une manière ou d'une autre.

Vous pouvez contourner cela en utilisant stdbuf -oL your-commandpour restaurer la mise en mémoire tampon de ligne (si votre commande utilise stdio) ou utiliser zptyau lieu de coprocpour simuler une sortie de terminal.

Avec bash, vous devrez vous fier à ddGNU timeoutsi disponible:

coproc your-command
while :; do
  timeout 10 dd bs=8192 count=1 2> /dev/null <&${COPROC[0]} && continue
  if (($? == 124)); then
    echo Timeout >&2
    kill "$!"
  fi
done

Au lieu de coproc, vous pouvez également utiliser la substitution de processus:

while :; do
  timeout 10 dd bs=8192 count=1 2> /dev/null <&3 && continue
  if (($? == 124)); then
    echo Timeout >&2
    kill "$!"
  fi
done 3< <(your-command)

(cela ne fonctionnera pas dans zshou ksh93parce $!qu'il ne contient pas le pid de your-commandlà).

Stéphane Chazelas
la source
1
Salut! Merci, est-il possible que vous puissiez commenter cela afin que je puisse comprendre ce que cela fait?
Benjojo
0

Je redirigerais STDOUT vers un fichier, puis j'utiliserais les tests d'horodatage de monit pour redémarrer le processus si le mtime du fichier est supérieur à un seuil.

Mark Wagner
la source