Docker如何在不调用命令行的情况下运行一个命令?
目前我正在学习Docker,并通过Dockerfile参考 ,特别是RUN
指令。 有两种forms的RUN
– 在shell中运行命令的shellforms,以及“不调用命令shell”(从注释部分引用)的execforms。
如果我正确理解了文档,我的问题是 – 如果Docker在没有shell的情况下运行一个命令,又该如何运行?
请注意, Can命令的答案可以在没有shell的情况下执行? 实际上并没有回答这个问题。
如果我正确地理解了你的问题,你问的是如何运行(特别是在docker的上下文中)而不用调用命令shell。
在Linux内核中运行的方式通常使用系统调用的exec
系列。
您将它传递给要运行的可执行文件的path以及需要通过execl调用传递给它的参数。
这实际上是你的shell(sh,bash,ksh,zsh)在引擎盖下做的。 你可以自己观察,如果你运行像strace -f bash -c "cat /tmp/foo"
在该命令的输出中,您将看到如下所示的内容:
execve("/bin/cat", ["cat", "/tmp/foo"], [/* 66 vars */]) = 0
真正发生的是bash在$PATH
查找cat
,然后发现cat
实际上是/bin/cat
可用的可执行二进制文件。 然后通过execve
调用它。 和正确的参数,你可以看到上面。
你可以简单地写一个C程序来做同样的事情。 这就是这样一个程序的样子:
#include<unistd.h> int main() { execl("/bin/cat", "/bin/cat", "/tmp/foo", (char *)NULL); return 0; }
每种语言都提供了与这些系统调用接口的自己的方式。 C做的,Python的做和Go,这也是大部分用来编写Docker的东西。 RUN
中的RUN
指令可能会转化为这些exec
调用中的一个。 你可以运行一个strace -f docker build
,然后在日志中调用exec
调用这个魔法。
通过shell和直接运行的唯一区别在于,你可能会失去所有你的shell为你做的东西,比如variables扩展,可执行文件search等等。
程序可以在没有shell的情况下执行另一个程序 你只需创build一个新的进程并在其上加载一个可执行文件,所以你不需要shell。 用户需要shell来启动程序,因为它是系统的用户界面。 另外,一个程序不能像没有shell的cd或rm那样运行一个内置的命令,因为没有可执行文件被find(有其他的方法,想法,但并不那么简单)。
在非常普遍的情况下,当docker exec允许你在容器中运行你想要的任何进程时, docker run
会启动容器的默认进程。
例如,通过docker run microsoft/iis
运行microsoft / iis容器将运行默认进程,即powershell。
但是你可以通过运行docker exec -i my_container cmd
来运行docker exec -i my_container cmd
看到这个答案的更多细节。