Với zsh
, bạn có thể làm:
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ưởng là sử dụng -t
tùy chọn sysread
đọc từ your-command
đầu ra với thời gian chờ.
Lưu ý rằng nó làm cho your-command
đầu ra của một đường ống. Có thể là your-command
bắt đầu đệm đầu ra của nó khi nó không đi đến một thiết bị đầu cuối, trong trường hợp đó bạn có thể thấy rằng nó không xuất ra bất cứ thứ gì trong một thời gian, nhưng chỉ vì bộ đệm đó, không phải vì nó bị treo .
Bạn có thể giải quyết vấn đề đó bằng cách sử dụng stdbuf -oL your-command
để khôi phục bộ đệm dòng (nếu lệnh của bạn sử dụng stdio) hoặc sử dụng zpty
thay vì coproc
giả mạo đầu ra của thiết bị đầu cuối.
Với bash
, bạn phải dựa vào dd
và GNU timeout
nếu có:
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
Thay vì coproc
, bạn cũng có thể sử dụng thay thế quá trình:
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)
(điều đó sẽ không hoạt động trong zsh
hoặc ksh93
bởi vì $!
không chứa pid your-command
ở đó).