GNU 超时的 POSIX 等价物?

Wil*_*ard 19 shell-script posix timeout

GNU 核心工具 timeout命令对于某些脚本情况非常方便,如果运行速度很快,则允许使用命令的输出,如果运行时间过长,则可以跳过它。

如何近似timeout仅使用 POSIX 指定实用程序的基本行为?


(我认为它可能涉及,和的组合wait,谁知道还有什么,但也许我错过了一种更简单的方法。)sleepkill

Gui*_*ido 5

我的方法是这样的:

  • 执行命令作为后台进程 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"
Run Code Online (Sandbox Code Playgroud)

结果TIMEOUT=10(命令在看门狗之前终止):

$ ./timeout.sh 10
Command completed
SIGTERM trap
End of execution
Run Code Online (Sandbox Code Playgroud)

结果TIMEOUT=1(看门狗在命令之前终止):

$ ./timeout.sh 1
Timeout expired
SIGTERM trap
End of execution
Run Code Online (Sandbox Code Playgroud)

结果TIMEOUT=5(看门狗和命令“几乎”同时终止):

./tst.sh 5
Timeout expired
Command completed
SIGTERM trap
End of execution
Run Code Online (Sandbox Code Playgroud)