我在 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僅適用于某些 vanilladocker exec foo bar格式命令,但現在我想用它來運行與docker exec bash -c "cd mydir && ./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 && ./my_shell.sh" " exit with code 127
我想知道如何修改原始函式以使其支持docker exec bash -c 用例。
uj5u.com熱心網友回復:
你的最后一個命令有一層額外的引號。
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通常也不是最好的設計,因為您需要對主機擁有無限制的管理員級別權限才能使用它,而且容器通常只運行一個行程。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/388090.html
