为什么要睡觉并在bash中等待?

mow*_*ker 13 bash docker

我在理解docker-compose.yml中服务的启动命令时遇到了麻烦。.yml中的两个相关行是:

command: "/bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g \"daemon off;\"'"
Run Code Online (Sandbox Code Playgroud)

entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"
Run Code Online (Sandbox Code Playgroud)

为什么将sleep命令发送到后台然后等待呢?为什么不直接做sleep 6h呢?另外,双美元符号只是逃脱了美元符号${!}吗?

我正在寻找将睡眠和等待结合使用的其他地方,但是似乎没有任何关于原因的解释:

  1. http://www.masteringunixshell.net/qa17/bash-how-to-wait-seconds.html
  2. /sf/answers/931093061/
  3. https://superuser.com/a/753984/98583

b0g*_*usb 7

当有人想及时处理信号时,在背景中睡觉然后等待是有意义的。

当bash在前台执行外部命令时,它不会处理任何接收到的信号,直到前台进程终止

此处详细说明)。

尽管第二个示例实现了信号处理程序,但对于第一个示例,休眠是否在前台执行都没有区别。没有陷阱,信号也不会传播到该nginx过程。为了使其响应SIGTERM信号,入口点应该是这样的:

/bin/sh -c 'nginx -g \"daemon off;\" & trap exit TERM; while :; do sleep 6h  & wait $${!}; nginx -s reload; done'
Run Code Online (Sandbox Code Playgroud)

要测试它:

docker run --name test --rm --entrypoint="/bin/sh" nginx  -c 'nginx -g "daemon off;" & trap exit TERM; while :; do sleep 20 & wait ${!}; echo running; done'
Run Code Online (Sandbox Code Playgroud)

停止容器

docker stop test
Run Code Online (Sandbox Code Playgroud)

或发送TERM信号(如果主进程未退出,则docker stop发送一个TERM后跟KILL

docker kill --signal=SIGTERM test
Run Code Online (Sandbox Code Playgroud)

这样,脚本立即退出。现在,如果我们删除wait ${!}陷阱,则在sleep结束时执行陷阱。所有这些对于第二个示例也都适用。

注意:在这两种情况下,其目的都是每12h检查一次证书更新,并每6h重新加载配置,如指南中所述。 这两个命令都可以。恕我直言,第一个示例中的额外等待只是开发人员的疏忽。

编辑:

上面的合理化似乎是为了提供背景睡眠的可能原因,可能会造成一些混乱。(有一篇相关的文章为什么在docker的后台使用nginx和“ daemon off”?)。

尽管上面答案中建议的命令是对问题中命令的改进,但它仍然存在缺陷,因为如链接文章中所述,nginx服务器应该是主要进程,而不是子进程。使用exec系统调用可以轻松实现。脚本变为:

'while :; do sleep 6h; nginx -s reload; done & exec nginx -g "daemon off;"'
Run Code Online (Sandbox Code Playgroud)

(在部分更多信息配置应用程序作为PID 1泊坞最佳实践

恕我直言,这种方法要好得多,因为不仅可以nginx监视而且还可以处理信号。nginx -s reload例如,还可以通过简单地将HUP信号发送到docker容器来手动完成配置重载()(请参阅控制nginx)。

  • `wait`是一个可以被中断的[shell内置](https://en.wikipedia.org/wiki/Shell_builtin)。睡眠是一个命令,并作为一个外部过程执行。睡眠和等待的重点是使“睡眠”可中断。 (2认同)