编程笔记

lifelong learning & practice makes perfect

翻译|如何在Bash脚本中使用`timeout`命令在指定时间后终止进程

前几天在工作中写了个Bash脚本,启动一个web服务器,并在继续执行后续操作之前等待Server完成启动。
该脚本运行良好,我们没有遇到任何问题,直到我们遇到一个无限循环。
Image 1: Airplane Tracks

我们使用Bash内置的until来检查web服务器是否已启动:

1
2
3
until curl --silent --fail-with-body 10.0.0.1:8080/health; do
sleep 1
done

运行良好。除非web服务器在启动过程中崩溃,脚本会无限期地sleep 1

这里有一个方便的工具:timeout。顾名思义,此命令会为其他命令添加超时。您可以指定要等待命令的时间限制,如果超过该时间,timeout会发送信号将其终止并以非零值退出。
默认情况下,timeout发送SIGTERM,但可以使用--signal标志更改它,例如timeout --signal=SIGKILL 1s foo
例如,timeout 1s sleep 5将在1秒后向sleep发送SIGTERM信号:

1
2
3
4
5
6
7
8
$ time timeout 1s sleep 4

real 0m1,004s
user 0m0,000s
sys 0m0,005s

$ echo $?
124

接下来要做的就是结合timeoutuntil

1
2
3
timeout 1m until curl --silent --fail-with-body 10.0.0.1:8080/health; do
sleep 1
done

唯一的问题是这不起作用。timeout需要一个可终止的命令,而until是一个shell关键字:你不能SIGTERM``until。我们不能将timeout与任何shell内置命令一起使用。
可行的一个方案是将该until包装在一个Bash进程中:

1
2
3
timeout 1m until curl --silent --fail-with-body 10.0.0.1:8080/health; do
sleep 1
done

另一种方法是将until移动到一个单独的Bash脚本中并对其进行timeout

1
timeout 1m ./until.sh

很遗憾我们不能直接将timeoutuntil一起使用,那样会很棒。但是将其包装在Bash进程/脚本中可以完成这项工作。

原文

欢迎关注我的其它发布渠道

Related Issues not found

Please contact @yiGmMk to initialize the comment