什么是 shell 表单和 exec 表单?
What are shell form and exec form?
什么是 shell 形式和 exec 形式的命令?
我已经阅读了几个文档以清楚地了解 shell 表单和 exec 表单。但一切都让我感到困惑。谁能帮忙弄清楚这两种形式有什么区别?
PS:虽然我在阅读 docker 文件说明 (ex: RUN, CMD, ENTRYPOINT
) 时遇到了这些术语,但我想知道它们之间的区别他们一般来说,而不是在 docker 上下文中。
docker shell 语法(它只是一个字符串,如 RUN
、ENTRYPOINT
和 CMD
)将 运行该字符串作为 /bin/sh -c
的参数。这为您提供了 shell 来扩展变量、子命令、管道输出、将命令链接在一起以及其他 shell 便利。
RUN ls * | grep $trigger_filename || echo file missing && exit 1
exec 语法只是 运行 您提供的二进制文件和您包含的参数,但没有 shell 解析的任何功能。在 docker 中,您使用 json 格式的数组来表示。
RUN ["/bin/app", "arg1", "arg2"]
exec 语法的优点是从启动的进程中删除 shell,这可能会抑制信号处理。在 shell 语法中使用 /bin/sh -c
重新格式化命令也可能会破坏入口点和 cmd 的连接。
entrypoint documentation 很好地涵盖了各种场景并对此进行了更详细的解释。
These following explanation are from the
Kubernetes In Action book(chapter 7)
.
首先,它们有两种不同的形式:
shell form—For example, ENTRYPOINT node app.js
exec form—For example, ENTRYPOINT ["node","app.js"]
其实区别是指定的命令是否在shell内部调用。我也想用一个例子来解释它们之间的主要区别。
ENTRYPOINT ["node", "app.js"]
这直接运行节点进程(不在 shell 内),如您在容器内列出进程 运行 所见:
$ docker exec 4675d ps x
PID TTY STAT TIME COMMAND
1 ? Ssl 0:00 node app.js
12 ? Rs 0:00 ps x
ENTRYPOINT node app.js
如果您使用 shell 形式(ENTRYPOINT 节点 app.js),这些将是容器的进程:
$ docker exec -it e4bad ps x
PID TTY STAT TIME COMMAND
1 ? Ss 0:00 /bin/sh -c node app.js
7 ? Sl 0:00 node app.js
13 ? Rs+ 0:00 ps x
如您所见,在这种情况下,主进程(PID 1)将是 shell 进程,而不是节点进程。节点进程(PID 7)将从 shell 开始。 shell 过程是不必要的,这就是为什么你应该始终使用 ENTRYPOINT 指令的 exec 形式。
扩展
的答案
这些是每条指令使用的推荐形式:
RUN: shell form, because of the shell features described in the below
source
ENTRYPOINT: exec form, because of the signal trapping described in the
below source
CMD: exec form, because of the signal trapping described in the below
source
Shell 特征、变量替换、信号捕获和转发、命令和入口点连接 在下面的例子中解释 link.
在这个非常好的博客中有更多内容:source
什么是 shell 形式和 exec 形式的命令?
我已经阅读了几个文档以清楚地了解 shell 表单和 exec 表单。但一切都让我感到困惑。谁能帮忙弄清楚这两种形式有什么区别?
PS:虽然我在阅读 docker 文件说明 (ex: RUN, CMD, ENTRYPOINT
) 时遇到了这些术语,但我想知道它们之间的区别他们一般来说,而不是在 docker 上下文中。
docker shell 语法(它只是一个字符串,如 RUN
、ENTRYPOINT
和 CMD
)将 运行该字符串作为 /bin/sh -c
的参数。这为您提供了 shell 来扩展变量、子命令、管道输出、将命令链接在一起以及其他 shell 便利。
RUN ls * | grep $trigger_filename || echo file missing && exit 1
exec 语法只是 运行 您提供的二进制文件和您包含的参数,但没有 shell 解析的任何功能。在 docker 中,您使用 json 格式的数组来表示。
RUN ["/bin/app", "arg1", "arg2"]
exec 语法的优点是从启动的进程中删除 shell,这可能会抑制信号处理。在 shell 语法中使用 /bin/sh -c
重新格式化命令也可能会破坏入口点和 cmd 的连接。
entrypoint documentation 很好地涵盖了各种场景并对此进行了更详细的解释。
These following explanation are from the
Kubernetes In Action book(chapter 7)
.
首先,它们有两种不同的形式:
shell form—For example, ENTRYPOINT node app.js
exec form—For example, ENTRYPOINT ["node","app.js"]
其实区别是指定的命令是否在shell内部调用。我也想用一个例子来解释它们之间的主要区别。
ENTRYPOINT ["node", "app.js"]
这直接运行节点进程(不在 shell 内),如您在容器内列出进程 运行 所见:
$ docker exec 4675d ps x
PID TTY STAT TIME COMMAND
1 ? Ssl 0:00 node app.js
12 ? Rs 0:00 ps x
ENTRYPOINT node app.js
如果您使用 shell 形式(ENTRYPOINT 节点 app.js),这些将是容器的进程:
$ docker exec -it e4bad ps x
PID TTY STAT TIME COMMAND
1 ? Ss 0:00 /bin/sh -c node app.js
7 ? Sl 0:00 node app.js
13 ? Rs+ 0:00 ps x
如您所见,在这种情况下,主进程(PID 1)将是 shell 进程,而不是节点进程。节点进程(PID 7)将从 shell 开始。 shell 过程是不必要的,这就是为什么你应该始终使用 ENTRYPOINT 指令的 exec 形式。
扩展
这些是每条指令使用的推荐形式:
RUN: shell form, because of the shell features described in the below source
ENTRYPOINT: exec form, because of the signal trapping described in the below source
CMD: exec form, because of the signal trapping described in the below source
Shell 特征、变量替换、信号捕获和转发、命令和入口点连接 在下面的例子中解释 link.
在这个非常好的博客中有更多内容:source