在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落案例,例如根据其父项名称做不同的事情。