Bash 脚本在后台运行一个程序,并将该程序的标准输出重定向到一个文件。如果程序在过去 x 秒内没有写入标准输出,我该如何终止该程序?
prog > out.txt &
PID=$!
...
wait $PID
我想象通过其他一些程序来检查输出的连续性。unbuffer
可能需要禁用输出缓冲。
unbuffer prog | ... > out.txt &
答案1
您可以/usr/bin/inotifywait
在脚本中使用,不带该-m
选项,因此监视会在第一个写入事件处停止,使用该选项,则如果在过去 10 秒内未注册写入修改事件,则-t 10
进程将退出并带有代码:2
#!/usr/bin/env bash
my_prog > out.txt &
my_prog_pid="$!"
my_watch_status=0
while [ "$my_watch_status" != "2" ]; do
/usr/bin/inotifywait -qq -t 10 -e modify out.txt 2>/dev/null &
wait $!
my_watch_status="$?"
done
kill -9 "$my_prog_pid"
exit <my exit_code>
- 选项
-qq
(“非常安静”)和标准错误重定向旨在/dev/null
抑制inotifywait
标准错误上的任何诊断信息和标准输出上的事件信息。 - 每次
out.txt
写入(10秒时间窗口内),都会启动一个新的10秒监控时间窗口。 kill -9
,又名信号杀死,用于不了解您my_prog
有序退出的可能要求。如果更喜欢优雅退出,则kill "$my_prog_pid"
可以使用简单退出。- 仅当在规定的时间窗口内未发生写入修改时,脚本才会终止
my_prog
并退出,可以选择退出代码。out.txt
- 请注意,在执行过程中,时间窗口不是完美的 10 秒。实际的时间窗口将略多于 10 秒(对于一个文件来说,可以认为是“毫秒”),因为建立监控需要一点时间。在您的情况下,这并不重要,因为您只监视一个文件,但如果您要以递归方式监视一棵大树(想象一下具有数千个文件的目录结构),它可能会变得非常重要。如果 10 秒的时间窗口对应用程序至关重要,您可能需要探索此处建议的方法之外的其他方法,以便不必重新建立对每个时间窗口跨度的监控,或者作为最坏的情况,每次在该时间窗口内发生写入事件时时间跨度。
答案2
它可能是这样的:
#!/bin/bash
while read line -t 10
do
echo $line
done
if [ $? -gt 128 ]
then
echo "Timeout occurred"
killall -SIGKILL procces
fi