【发布时间】:2020-04-16 09:37:47
【问题描述】:
我正在从我的 Go 程序执行 docker-compose 可执行文件。为了配置它,我将 docker-compose 配置直接通过管道传输到 docker-compose 的标准输入。这在大多数情况下都可以正常工作,代码大致如下所示(为简单起见,我删除了代码 sn-ps 中的所有错误处理):
args = append([]string{"-f", "-"}, args...)
cmd := exec.Command("docker-compose", args...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Stdin = strings.NewReader(input)
cmd.Run()
args 是传递给 docker-compose 的参数,input 是 docker-compose 配置为 YAML 字符串。
虽然这适用于大多数情况,但对于交互式命令它会失败。标准输入未连接到 os.stdin,命令失败。我可以使用以下代码获取交互式命令:
cmd := exec.Command("docker-compose", args...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Stdin = os.Stdin
cmd.Run()
但这没有管道配置,我最终需要这样做。我尝试以某种方式组合这些版本,但无法正常工作:
input, _ := getDockerComposeAsYaml(config)
args = append([]string{"-f", "-"}, args...)
cmd := exec.Command("docker-compose", args...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
stdin, _ := cmd.StdinPipe()
go func() {
//defer stdin.Close()
io.WriteString(stdin, input)
}()
cmd.Run()
我在明确关闭和不关闭标准输入的情况下尝试了上述代码,尽管所需的行为应该是不关闭它,因为我想保持标准输入打开以供交互使用。不关闭程序只会永远挂起,关闭标准输入它不会按预期交互工作。
将已执行程序的标准输入连接到 os.stdin,同时仍然能够在开始时通过管道输入一些数据的正确方法是什么?
【问题讨论】:
标签: go