什么是shell形式和exec形式的命令?
我已经通过几个文档来清楚地了解shell形式和exec形式。但所有人看起来都让我感到困惑。任何人都可以帮助弄清楚这两种形式有什么区别?
PS :虽然我在浏览docker文件指令(ex: RUN, CMD, ENTRYPOINT
)时遇到过这些术语,但我想知道它们之间的区别,而不是在docker上下文中。
答案 0 :(得分:10)
docker shell语法(只是RUN
,ENTRYPOINT
和CMD
的字符串)将该字符串作为/bin/sh -c
的参数运行。这为您提供了一个shell来扩展变量,子命令,管道输出,链接命令以及其他shell便利。
RUN ls * | grep $trigger_filename || echo file missing && exit 1
exec语法只是运行您提供的二进制文件和您包含的args,但没有shell解析的任何功能。在docker中,用一个json格式的数组来表示它。
RUN ["/bin/app", "arg1", "arg2"]
exec语法的优点是从启动的进程中删除shell,这可能会禁止信号处理。在shell语法中使用/bin/sh -c
重新格式化命令也可能会破坏入口点和cmd的连接。
答案 1 :(得分:9)
These following explanation are from the
Kubernetes In Action book(chapter 7)
。
首先,它们具有两种不同的形式:
外壳形式-例如, ENTRYPOINT节点app.js
exec表单-例如, ENTRYPOINT [“ node”,“ app.js”]
实际上区别是指定的命令是否在外壳内部调用。我也想通过一个例子来解释它们之间的主要区别。
ENTRYPOINT [“ node”,“ app.js”]
这将直接运行节点进程(不在外壳内部),如列出容器中运行的进程所示:
$ docker exec 4675d ps x
PID TTY STAT TIME COMMAND
1 ? Ssl 0:00 node app.js
12 ? Rs 0:00 ps x
ENTRYPOINT节点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进程是不必要的,这就是为什么您应该始终使用 ENTRYPOINT 指令的exec形式的原因。