GNU coreutilstimeout
命令对于某些脚本编写情况非常方便,如果命令运行速度很快,则允许使用命令的输出,如果命令运行时间太长,则可以跳过它。
如何近似timeout
仅使用 POSIX 指定实用程序的基本行为?
wait
(我认为它可能涉及、sleep
、和谁知道还有什么的组合kill
,但也许我缺少一种更简单的方法。)
答案1
我的方法是这样的:
作为后台进程1执行命令
执行“看门狗定时器”作为后台进程2
设置处理程序以捕获父 shell 中的终止信号
等待两个过程完成。首先终止的进程向父进程发送终止信号。
父进程的陷阱处理程序通过作业控制杀死两个后台进程(其中一个进程已根据定义终止,但该杀死将是无害的无操作,因为我们没有使用 PID,请参见下文)
我试图通过使用 shell 的作业控制 ID(在该 shell 实例中是明确的)来识别要终止的后台进程,而不是系统 PID,从而规避注释中提到的可能的竞争条件。
#!/bin/sh
TIMEOUT=$1
COMMAND='sleep 5'
function cleanup {
echo "SIGTERM trap"
kill %1 %2
}
trap cleanup SIGTERM
($COMMAND; echo "Command completed"; kill $$) &
(sleep $TIMEOUT; echo "Timeout expired"; kill $$) &
wait
echo "End of execution"
结果TIMEOUT=10
(命令在看门狗之前终止):
$ ./timeout.sh 10
Command completed
SIGTERM trap
End of execution
结果TIMEOUT=1
(看门狗在命令之前终止):
$ ./timeout.sh 1
Timeout expired
SIGTERM trap
End of execution
结果TIMEOUT=5
(看门狗和命令“几乎”同时终止):
./tst.sh 5
Timeout expired
Command completed
SIGTERM trap
End of execution