如何使 timeout(1) 在 cron 中的行为与在交互式 shell 中的行为一样

如何使 timeout(1) 在 cron 中的行为与在交互式 shell 中的行为一样

在交互式 bash 中运行此命令:

$ timeout 1 sleep 2; echo $?
124

返回1241 秒后,如预期以及 timeout(1) 中记录的那样。

但是,如果我将其作为 cron 作业运行,或者将其作为命令字符串提供给 bash,则不会:

$ bash -c "timeout 1 sleep 2; echo $?"
0

添加-i到 bash 调用没有帮助,使用 timeout(1) 参数也没有帮助--foreground。我也尝试使用 ksh 和 zsh 进行同样的操作,但总是得到相同的结果,所以我猜这一定是 timeout(1) 工作方式固有的问题。

我在网上搜索了一下,发现这可能与信号如何通过进程组进行有关,但我找不到如何在非交互式情况下使超时按预期工作的解决方案。

关于如何实现这一点有什么提示吗?最终,我想要的是在 cron 中运行一个可能永远阻塞的命令,并且我想可靠地检测这种情况。

答案1

由于双引号,$?正在扩展调用 bash 命令。它被替换为以前的命令(第一个exit $?

快速演示

bash -c 'exit 42'
bash -c "timeout 1 sleep 2; echo $?"   # => 42

解决方案是使用单引号这样当前交互式 bash 进程就不会扩展变量

bash -c 'timeout 1 sleep 2; echo $?'   # => 124

答案2

您可以尝试如下运行命令:

bash -c "timeout 1 sleep 2"; echo $?

相关内容