Zabij proces, jeśli przez pewien czas będzie cicho

9

Mam narzędzie, które ma nieprzyjemny nawyk wyciszania się i pozostawania w nim, już wiem, jak długo to trwa, więc używam go timeoutdo walki, ale czasami robi to wcześniej. Czy istnieje narzędzie podobne do timeouttego, które zabije proces, jeśli przestanie kierować wyjście na standardowe wyjście?

Benjojo
źródło

Odpowiedzi:

8

Dzięki zshmożesz wykonać:

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

Chodzi o to, aby użyć -topcji sysreadodczytu z your-commandwyniku z przekroczeniem limitu czasu.

Zauważ, że czyni your-commandto wyjście potokiem. Może się zdarzyć, że your-commandzacznie buforować dane wyjściowe, gdy nie przejdzie do terminala, w którym to przypadku może się okazać, że przez jakiś czas nic nie wyświetla, ale tylko z powodu buforowania, a nie dlatego, że w jakiś sposób został zawieszony .

Możesz obejść ten problem, używając stdbuf -oL your-commandprzywracania buforowania linii (jeśli twoje polecenie używa stdio) lub użyj zptyzamiast coprocsfałszować wyjście terminala.

Z bash, będziesz musiał polegać na ddGNU, timeoutjeśli jest dostępny:

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

Zamiast tego coprocmożesz również użyć podstawienia procesu:

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)

(to nie zadziała zshlub ksh93ponieważ $!nie zawiera pid your-commandtam).

Stéphane Chazelas
źródło
1
Cześć! Dzięki, czy możesz to skomentować, abym mógł zrozumieć, co to robi?
Benjojo
0

Przekierowałbym STDOUT do pliku, a następnie użyłem testowania sygnatury czasowej monitora, aby zrestartować proces, jeśli mtime pliku jest większy niż próg.

Mark Wagner
źródło