ฆ่าโพรเซสถ้ามันเงียบไปชั่วระยะเวลาหนึ่ง


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เพราะ$!ไม่มี pid ของที่your-commandนั่น)


1
Hi! ขอบคุณเป็นไปได้หรือไม่ที่คุณสามารถแสดงความคิดเห็นนี้เพื่อให้ฉันเข้าใจว่าสิ่งนี้กำลังทำอะไรอยู่
Benjojo

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.