什么是shell形式和exec形式?

Muf*_*eed 11 shell exec docker

什么是shell形式和exec形式的命令?
我已经通过几个文档来清楚地了解shell形式和exec形式.但所有人看起来都让我感到困惑.任何人都可以帮助弄清楚这两种形式有什么区别?

PS:虽然我在浏览docker文件指令(ex: RUN, CMD, ENTRYPOINT)时遇到了这些术语,但我想知道它们之间的区别,而不是在docker上下文中.

fgu*_*gul 19

These following explanation are from the Kubernetes 在行动 book(chapter 7)

首先,它们有两种不同的形式:

  • shell 形式——例如ENTRYPOINT 节点 app.js

  • exec 形式——例如,ENTRYPOINT ["node","app.js"]

其实区别在于指定的命令是否在shell中调用。我也想用一个例子来解释它们之间的主要区别。

入口点 ["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
Run Code Online (Sandbox Code Playgroud)

入口点节点 app.js

如果您使用了 shell 表单(ENTRYPOINT node 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
Run Code Online (Sandbox Code Playgroud)

如您所见,在这种情况下,主进程(PID 1)将是 shell 进程而不是节点进程。节点进程 (PID 7) 将从该 shell 启动。shell 进程是不必要的,这就是为什么你应该总是使用ENTRYPOINT指令的 exec 形式。


BMi*_*tch 12

泊坞窗shell语法(这仅仅是一个字符串作为RUN,ENTRYPOINTCMD)将运行字符串作为参数/bin/sh -c.这为您提供了一个shell来扩展变量,子命令,管道输出,链接命令以及其他shell便利.

RUN ls * | grep $trigger_filename || echo file missing && exit 1
Run Code Online (Sandbox Code Playgroud)

exec语法只是运行您提供的二进制文件和您包含的args,但没有shell解析的任何功能.在docker中,用json格式的数组表示.

RUN ["/bin/app", "arg1", "arg2"]
Run Code Online (Sandbox Code Playgroud)

exec语法的优点是从启动的进程中删除shell,这可能会禁止信号处理./bin/sh -c在shell语法中重新格式化命令也可能会破坏入口点和cmd的连接.

  • 很好的答案,但它引入了很多新术语。如果这能解释得更简单一点,我会非常高兴。 (3认同)