【问题标题】:How to run `docker exec -it <container_name> bash -c "some commands"` using golang sdk如何使用 golang sdk 运行`docker exec -it <container_name> bash -c "some commands"`
【发布时间】:2022-01-21 19:23:30
【问题描述】:

我在 golang 中使用 docker 的 sdk 来执行 docker exec 命令。

func (dn *dockerNode) execCommand(ctx context.Context, cmd []string) (*execResult, error) {
    execId, err := dn.cl.ContainerExecCreate(ctx, dn.contId, types.ExecConfig{
        AttachStderr: true,
        AttachStdout: true,
        Tty:          true,
        Cmd:          cmd,
    })

    if err != nil {
        return nil, fmt.Errorf(
            "cannot create command \"%s\":\n %v",
            strings.Join(cmd, " "),
            err,
        )
    }

    res, err := dn.InspectExecResp(ctx, execId.ID)
    if err != nil {
        return nil, fmt.Errorf(
            "cannot execute command \"%s\":\n %v",
            strings.Join(cmd[:], " "),
            err,
        )
    }

    if res.exitCode != 0 {
        return &res, fmt.Errorf(
            "command \"%s\" exit with code %d:\n %+v",
            strings.Join(cmd[:], " "),
            res.exitCode,
            res)
    }

    return &res, nil
}

这个dn.execCommand 只适用于一些普通的docker exec foo bar 格式命令,但现在我想用它来运行相当于docker exec bash -c "cd mydir &amp;&amp; ./my_shell.sh" 的东西。这是因为cd 命令仅适用于docker exec bash -c。我尝试通过

    res, err = dn.execCommand(
        ctx,
        []string{
            "bash",
            "-c",
            "\"cd mydir && ./my_shell.sh\"",
        },
    )

但它给了我command "bash -c "cd mydir &amp;&amp; ./my_shell.sh" " exit with code 127

我想知道如何修改原始函数以使其支持docker exec bash -c 用例。

【问题讨论】:

    标签: bash docker go


    【解决方案1】:

    你的最后一个命令有一个额外的引号层。

    command := []string{
            "bash",
            "-c",
            "cd mydir && ./my_shell.sh",
    //      ^^no quotes inside string^^
    }
    

    如果您要在主机上运行类似的命令

    bash -c "cd mydir && ./my_shell.sh"
    

    shell 会获取双引号字符串并将其转换为单个单词,然后丢弃引号。您可以通过将单词echo 放在命令行前面来部分看到这一点,因此处理后的命令被打印出来而不是执行;双引号将消失。你正在运行的更类似于

    bash -c '"cd mydir && ./my_shell.sh"'
    

    还要注意"github.com/docker/docker/api/types".ExecConfig 结构包含WorkingDir 字段,因此您可以避免使用此包装器。编写docker exec 脚本通常也不是最佳设计,因为您需要对主机拥有无限的管理员级别权限才能使用它,而且容器通常只运行一个进程。

    【讨论】:

    • 谢谢! WorkingDir 字段非常适合我!!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-12-16
    • 1970-01-01
    • 1970-01-01
    • 2017-09-16
    • 1970-01-01
    • 2014-12-12
    • 2018-10-17
    相关资源
    最近更新 更多