在docker入口脚本中使用exec有什么作用?
例如在redis官方映像中:
https://github.com/docker-library/redis/blob/master/2.8/docker-entrypoint.sh
#!/bin/bash set -e if [ "$1" = 'redis-server' ]; then chown -R redis . exec gosu redis "$@" fi exec "$@"
为什么不像往常一样运行这些命令而没有exec之前呢?
正如@Peter Lyons所说,使用exec将取代父进程,而不是有两个进程在运行。
在Docker中,信号被正确代理是非常重要的。 例如,如果Redis是在没有exec的情况下启动的,那么在docker stop
时不会收到SIGTERM
,也不会有干净closures的机会。 在某些情况下,这可能会导致数据丢失或僵尸进程。
如果您确实启动subprocess(即不使用exec),则父进程将负责处理和转发适当的信号。 这是在容器中运行多个进程时最好使用supervisord或类似的原因之一,因为它将适当地转发信号。
如果没有可执行文件,父shell进程会存活并等待孩子退出。 通过exec,subprocess完全取代了父进程,所以当父母在分岔孩子之后没有任何事情发生的时候,我会认为exec
更精确/正确/高效。 在事物的macros伟计划中,我认为将其分类为次要优化可能是安全的。
没有执行
- 父shell启动
- 父母的shell叉子
- 孩子跑
- 孩子退出
- 父shell退出
与执行
- 父shell启动
- 父母分岔孩子,用小孩取代自己
- 子程序运行接pipeshell的进程
- 孩子退出
把它看作是像尾recursion这样的优化。
如果运行另一个程序是shell脚本的最后一个行为,那么shell就不需要在新进程中运行该程序并等待它。 使用exec
,shell进程用程序replace自己。
在任何一种情况下,shell脚本的退出值都是相同的1 。 无论程序最初叫做shell脚本,都会看到一个退出值等于exec`ed程序的退出值(如果程序找不到,则退出127)。
1个模块的angular落案例,例如根据其父项名称做不同的事情。