Убейте процесс, если он успокоится в течение определенного времени

У меня есть утилита, которая имеет неприятную привычку тишиться и оставаться там, я уже знаю, как долго в процессе она это делает, поэтому я использую timeout для борьбы с этим, но иногда он делает это до этого времени. Есть ли инструмент, подобный timeout , который убьет процесс, если он перестанет направлять вывод на stdout?

  • Может ли написать stdout место противодавления в процессе?
  • Как ограничить количество строк выходом команды в bash?
  • Как отправить stderr в stdout с помощью трубы в другую команду?
  • Как ничего не делать вечно элегантным способом?
  • Чтение и запись в файл из stdin и stdout
  • Почему опция -v с rm показывает записи с обратным отсчетом и обычной цитатой?
  • grep, как подавить отображение несогласованного файла?
  • Любой способ бросить несколько строк справочной страницы, чтобы показать на stdout для справки?
  • 2 Solutions collect form web for “Убейте процесс, если он успокоится в течение определенного времени”

    С помощью zsh вы можете:

     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 

    Идея состоит в использовании опции -t для sysread для чтения с выхода your-command с таймаутом.

    Обратите внимание, что он выводит your-command на канал. Возможно, your-command запускает буферизацию своего вывода, когда она не переходит на терминал, и в этом случае вы можете обнаружить, что она ничего не выводит через какое-то время, а только из-за этой буферизации, а не потому, что она как-то висела ,

    Вы можете обойти это, используя stdbuf -oL your-command для восстановления буферизации строк (если ваша команда использует stdio) или использовать zpty вместо coproc для подделки вывода терминала.

    При использовании bash вам придется полагаться на timeout dd и GNU, если он доступен:

     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 

    Вместо coproc вы также можете использовать замену процесса:

     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) 

    (это не будет работать в zsh или ksh93 потому что $! не содержит pid your-command там).

    Я перенаправлял STDOUT к файлу, а затем использовал timestamp-тестирование monit для перезапуска процесса, если mtime файла больше порога.

    Linux и Unix - лучшая ОС в мире.