Beenden Sie einen Prozess, wenn er für eine bestimmte Zeit ruhig wird

9

Ich habe ein Dienstprogramm, das die böse Angewohnheit hat, ruhig zu werden und dort zu bleiben. Ich weiß bereits, wie lange es in dem Prozess dauert, also benutze ich es timeout, um dies zu bekämpfen, aber manchmal tut es es vor dieser Zeit. Gibt es ein ähnliches Tool, timeoutdas den Prozess abbricht, wenn die Ausgabe nicht mehr an stdout weitergeleitet wird?

Benjojo
quelle

Antworten:

8

Mit zshkönnten Sie tun:

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

Die Idee war, die -tOption sysreadzu verwenden, your-commandmit einem Timeout aus der Ausgabe zu lesen .

Beachten Sie, dass die your-commandAusgabe dadurch zu einer Pipe wird. Es kann sein, dass your-commanddie Ausgabe gepuffert wird, wenn sie nicht an ein Terminal gesendet wird. In diesem Fall stellen Sie möglicherweise fest, dass sie in einer Weile nichts mehr ausgibt, sondern nur aufgrund dieser Pufferung, nicht weil sie irgendwie hängen bleibt.

Sie können dies umgehen, indem stdbuf -oL your-commandSie die Zeilenpufferung wiederherstellen (wenn Ihr Befehl stdio verwendet) oder zptystattdessen coproceine Terminalausgabe fälschen.

Mit bashmüssten Sie sich auf ddund GNU verlassen, timeoutfalls verfügbar:

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

Stattdessen coprockönnen Sie auch die Prozessersetzung verwenden:

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)

(das funktioniert nicht in zshoder ksh93weil $!es nicht die PID von your-commanddort enthält).

Stéphane Chazelas
quelle
1
Hallo! Danke, ist es möglich, dass Sie dies kommentieren, damit ich verstehen kann, was dies tut?
Benjojo
0

Ich würde STDOUT in eine Datei umleiten und dann den Zeitstempeltest von monit verwenden , um den Prozess neu zu starten, wenn die mtime der Datei einen Schwellenwert überschreitet.

Mark Wagner
quelle