'docker start'是否执行CMD命令?
我相信@jripoll不正确,它似乎运行,这是第一次运行与docker run
上docker start
过的命令。
这里有一个简单的例子来测试:
首先创建一个shell脚本来运行名为tmp.sh
:
echo "hello yo!"
然后运行:
docker run --name yo -v "$(pwd)":/usr/src/myapp -w /usr/src/myapp ubuntu sh tmp.sh
,将打印hello yo!
。
现在再次启动它:
docker start -ia yo
它将每次运行那个时候再次打印。
不,只有在执行'docker run'才能运行基于图像的容器时,才会执行CMD命令。
在文档中: 当以shell或exec格式使用时,CMD指令设置当运行图像时要执行的命令。
当你做码头工人开始,你叫api/client/start.go
,这就要求:
cli.client.ContainerStart(containerID)
这就要求engine-api/client/container_start.go
:
cli.post("/containers/"+containerID+"/start", nil, nil, nil)
的码头工人守护进程API调用daemon/start.go
:
container.StartMonitor(daemon, container.HostConfig.RestartPolicy)
容器监视器在012中运行容器:
m.supervisor.Run(m.container, pipes, m.callback)
默认情况下,码头工人守护进程是这里的主管,在daemon/daemon.go:
daemon.execDriver.Run(c.Command, pipes, hooks)
而且execDriver创造了daemon/execdriver/windows/exec.go
命令行:
createProcessParms.CommandLine, err = createCommandLine(processConfig, false)
使用的processConfig.Entrypoint
andprocessConfig.Arguments
in daemon/execdriver/windows/commandlinebuilder.go
:
// Build the command line of the process
commandLine = processConfig.Entrypoint
logrus.Debugf("Entrypoint: %s", processConfig.Entrypoint)
for _, arg := range processConfig.Arguments {
logrus.Debugf("appending %s", arg)
if !alreadyEscaped {
arg = syscall.EscapeArg(arg)
}
commandLine += " " + arg
}
那些ProcessConfig.Arguments
被填充在daemon/container_operations_windows.go
:
processConfig := execdriver.ProcessConfig{
CommonProcessConfig: execdriver.CommonProcessConfig{
Entrypoint: c.Path,
Arguments: c.Args,
Tty: c.Config.Tty,
},
,与c.Args
是一个容器的参数(runtile参数或CMD
)
所以肯定的, 'CMD
' 的命令是在'docker start
'后执行。
如果您希望您的容器每次都运行相同的可执行文件,那么您应该考虑将ENTRYPOINT
与CMD
结合使用。
注意:不要混淆RUN
和CMD
。 RUN实际上运行一个命令并提交结果; CMD
在构建时不执行任何操作,但指定图像的预期命令。
检查这个问题:CMD和入口点在Dockerfile之间的区别是什么?(http://*.com/q/21553353/4677231)为了解大'CMD','入口点' – sEpmein 2015-03-28 13:00:43