使用sleep and wait -n在bash,竞赛条件下实现简单超时?

时间:2018-06-21 18:45:21

标签: bash shell

如果我在bash脚本中这样做:

sleep 10 &
sleep_pid=$!
some_command &
wait -n
cmd_pid=$!

if kill -0 $sleep_pid 2> /dev/null; then
    # all ok
    kill $sleep_pid
else
    # some_command hung
    ...code to log diagnostics and then kill -9 $cmd_pid...
fi

其中some_command应该很快,但是由于极少的错误而可能挂起。

那么在“ wait -n”开始之前是否有可能完成并清除some_command的风险,所以只有等待的睡眠了吗?还是通过一个命令后的“&”来保证外壳程序在处理完下一行输入之前不会在其上调用waitpid()?

它在交互式外壳中工作。如果您这样做:

sleep 10 &
sleep 0 &
wait -n

然后,即使您在运行它之前等待了几秒钟,“ wait -n”也会立即返回。但是我不确定非交互式shell是否可以信任它?

编辑:澄清对诊断的需求和一些语法。

3 个答案:

答案 0 :(得分:1)

我相信您可以使用timeout命令执行此操作。
http://man7.org/linux/man-pages/man1/timeout.1.html

timeout 10s command_to_run

您可以检查timeout命令的退出状态以了解其是否超时。

timeout 2s sleep 10

if [[ $? -gt 0 ]]; then
  echo "it timed out"
else
  echo "It was successful"
fi

答案 1 :(得分:0)

通过使用$!变量,我们避免依赖于交互式作业控制功能。试试这个:

...long executing command... &
pid_long=$!

sleep 3 &
pid_sleep=$!

wait -n
kill -KILL $pid_long

这里的问题是PID回收。不过,不太可能在3秒内发生。

如果命令在睡眠之前完成(并且其PID尚未回收到新进程),则kill会产生错误消息;我们可以将其传送到/dev/null

我们可能还应该kill睡觉,以防万一 缠绵。

答案 2 :(得分:0)

正如@CharlesDuffy在评论中指出的那样,答案是否定的,没有种族(只要它在非交互式shell中运行)。

而且(在非交互式shell中)也无需确保命令后立即进行等待,因为非交互式shell不会自动获得子级。

但是我想应该将其包装在一个子外壳中,因此由于先前已启动了一些不相关的后台作业,因此“ wait -n”不会提早返回。