我注意到docker的许多entrypoint.sh脚本都是这样的:
#!/bin/bash
set -e
... code ...
exec "$@"
Run Code Online (Sandbox Code Playgroud)
什么是set -e和exec "$@"为什么?
Mat*_*hew 55
它基本上采用所有额外的命令行参数并将它们作为命令执行.目的基本上是"在此.sh脚本中执行所有操作,然后在同一个shell中运行用户在命令行上传入的命令".
看到:
BMi*_*tch 25
set -e如果正在运行的任何命令以非零退出代码退出,则设置shell选项以立即退出.该脚本将返回失败命令的退出代码.从bash手册页:
set -e:
如果管道(可能包含单个简单命令),列表或复合命令(请参阅上面的SHELL GRAMMAR),则立即退出,并以非零状态退出.如果失败的命令是紧跟在while或until关键字之后的命令列表的一部分,在if或elif保留字之后的测试的一部分,在&&或||中执行的任何命令的一部分,则shell不会退出 list除了最后的&&或||之后的命令,管道中的任何命令但是最后一个命令,或者命令的返回值是否被反转!如果子shell以外的复合命令返回非零状态,因为在忽略-e时命令失败,则shell不会退出.ERR上的陷阱(如果已设置)将在shell退出之前执行.此选项分别适用于shell环境和每个子shell环境(请参阅上面的COMMAND EXECUTION ENVIRONMENT),并且可能会导致子shell在执行子shell中的所有命令之前退出.
如果复合命令或shell函数在忽略-e的上下文中执行,则复合命令或函数体中执行的任何命令都不会受-e设置的影响,即使设置了-e并且命令返回失败状态.如果复合命令或shell函数在忽略-e的上下文中执行时设置-e,则在复合命令或包含函数调用的命令完成之前,该设置将不起作用.
exec "$@"通常用于使入口点通过然后运行docker命令.它将使用"$@"指向的命令替换当前运行的shell .默认情况下,该变量指向命令行参数.
如果您的图像的入口点指向entrypoint.sh,并且您将容器运行为docker run my_image server start,则将转换为entrypoint.sh server start在容器中运行.在exec行entrypoint.sh,作为pid 1运行的shell将用命令替换它自己server start.
这对于信号处理至关重要.如果不使用exec,server start上面的示例将作为另一个pid运行,退出后,您将返回到shell脚本.对于pid 1中的shell,默认情况下将忽略SIGTERM.这意味着docker stop发送到您的容器的优雅停止信号将永远不会被server进程接收.在10秒后(默认情况下),docker stop将放弃正常关机并发送强制您的应用程序退出的SIGKILL,但由于潜在的数据丢失或关闭的网络连接,应用程序开发人员可能已经编码,如果他们收到信号.这也意味着你的容器总是需要10秒才能停止.
请注意,shell命令状shift,并set --,你可以改变的价值"$@".例如,这是脚本的一小部分,/bin/sh -c "..."如果您使用docker的shell语法,则会从命令中删除该命令CMD:
# convert `/bin/sh -c "server start"` to `server start`
if [ $# -gt 1 ] && [ x"$1" = x"/bin/sh" ] && [ x"$2" = x"-c" ]; then
shift 2
eval "set -- $1"
fi
....
exec "$@"
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
34484 次 |
| 最近记录: |