linux - docker api ContainerExecInspect 无法获得正确的退出代码

标签 linux shell go docker

我正在使用 docker engine-api(github.com/docker/engine-api) 来执行一些命令

我使用 client.ContainerExecCreate,然后使用 client.ContainerExecInspect 来运行我的命令,然后获取命令退出代码(我在同一容器中运行多个命令,因此从 ContainerInspect 获取的退出代码对我来说毫无用处。)

这是我用来在容器中执行命令的函数

http://pastebin.com/rTNVuv9T

但 ContainerExecInspect 有时会返回错误的值,因为有时 ContainerExecInspect 在命令退出之前被调用并且它说退出代码为零,这是错误的

然后我写了一个测试用例来测试它

http://pastebin.com/PED1Rf4k

结果不会是233,会是0

我已经设置了 ExecConfig.Detach = true 和 ExecStartCheck.Detach = true,但没有帮助

有什么办法可以等到命令退出然后获取退出码?

添加:

因为我运行的一些命令是 shell 脚本而不是可执行文件,所以我想我需要在/bin/bash 前加上前缀,然后等待 container 退出,这不是我想要的,我想要等待命令退出,容器仍在运行

最佳答案

我想现在我可以解决我的问题了

重点是在使用containerExecAttach时会暴露被劫持的连接,我可以通过读取连接直到EOF来判断命令是否退出

接下来有几点需要设置

  1. 应将 ExecConfig AttachStdout 设置为 true
  2. 然后从被劫持的conn中读取

这是一个示例代码

atinfo, err := cli.ContainerExecAttach(ctx, execID, ec)

// error handling

defer atinfo.Close()
c = atinfo.Conn 

one := make([]byte, 1)
_, err = c.Read(one)

if err == io.EOF {
    println("Connection closed")
}

这将等到命令执行完成

ExecConfig 设置为

ec.Detach = false
ec.Tty = false
ec.AttachStdout = true

关于linux - docker api ContainerExecInspect 无法获得正确的退出代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40492724/

相关文章:

linux编译多个java文件

c - 确定对cgroup任务的写入失败是否是持久性的?

linux - 避免在 bash 命令中使用临时文件

windows - 如何查看当前操作系统是Windows、Linux还是OSX?

linux - 自动更改bash脚本中的变量

mysql - Mongo Restore 在 AWS 上的分片集群环境中显示无可访问服务器错误?

bash - 如何列出在 Git 中更改了文件的所有文件夹名称?

sql - Go 应用程序在 FLOATS 上使用 GROUP_CONCAT 进行 SQL 查询返回 []uint8 而不是实际的 []float64

mongodb - 计算数组中元素的数量

go - 用 Go 判断 Stdin 是否有数据