gpt4 book ai didi

go - 使用以编程方式编写并连接到os.stdin的stdin执行命令

转载 作者:行者123 更新时间:2023-12-01 22:23:49 27 4
gpt4 key购买 nike

我正在从Go程序中执行docker-compose可执行文件。要配置它,我将docker-compose配置直接通过管道传递到docker-compose的stdin。在大多数情况下,这都可以正常工作,代码大致如下所示(为简单起见,我删除了代码段中的所有错误处理):

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是作为YAML字符串的docker-compose配置。

尽管这在大多数情况下都有效,但对于交互式命令而言却失败了。 Stdin未连接到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()

我尝试了上面的代码,无论是否显式关闭stdin,但所需的行为应该是不关闭stdin,因为我想保持stdin打开以进行交互使用。如果不关闭程序,则该程序将永远挂起,而关闭stdin则无法按预期进行交互。

将已执行程序的stdin连接到os.stdin,同时仍然能够在开始时通过管道传输一些正确的方法是什么?

最佳答案

写入stdin(使用cmd.StdinPipe创建的管道)的goroutine应该:

  • 编写input字符串
  • 然后循环到真正的os.Stdin,将获取的所有内容写入stdin
  • os.Stdin上遇到EOF时,请明确关闭stdin

  • 但是,子进程可能在 os.Stdin关闭之前退出。在这种情况下,管道( stdin将由 exec.Command关闭)。您的循环应检查是否有闭合的 stdin,如果发生则退出goroutine。

    关于go - 使用以编程方式编写并连接到os.stdin的stdin执行命令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61247109/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com