Вбийте процес, якщо він проходить тихо протягом певного часу


9

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

Відповіді:


8

З 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, вам доведеться покластися ddі на GNU, timeoutякщо вони доступні:

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тому, $!що не містить your-commandтамтешньої сторінки).


1
Привіт! Дякую, чи можливо ви могли прокоментувати це, щоб я зрозумів, що це робить?
Бенджоджо

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.