管道命令输出时结果不一致

时间:2020-07-05 17:04:44

标签: docker go debian

我正在运行Windows的Docker桌面的Debian docker容器内执行命令(实际上是各种bash脚本),并得到如下输出:

func execute(cmd *exec.Cmd, write func([]byte)) {
    cmdReader, err := cmd.StdoutPipe()
    if err != nil {
        write([]byte(fmt.Sprintf("error getting stdout pipe: %v", err)))
        return
    }
    cmd.Stderr = cmd.Stdout

    scanner := bufio.NewScanner(cmdReader)

    go func() {
        for scanner.Scan() {
            write(scanner.Bytes())
        }
    }()

    err = cmd.Start()
    if err != nil {
        write([]byte(err.Error()))
        return
    }

    err = cmd.Wait()
    if err != nil {
        write([]byte(err.Error()))
    }
}

对于更复杂的命令/脚本之一,扫描器似乎在没有错误地完成命令输出之前就已经完成了。在某些运行中,我得到了期望的完整输出,而在其他运行中,它缩短了。

我连接到容器并多次手动执行命令/脚本,并且总是得到期望的完整输出,因此使我认为此代码有问题。我了解scanner.Bytes()返回的基础切片可能会被下一次对scanner.Scan()的调用所覆盖,但是在scanner.Scan()完成之前不会再对write进行调用,所以我不会认为这里没有比赛条件。

要检查go例程中的扫描仪是否有问题,我像这样尝试过,但结果不一致。我在这里想念什么?

func execute(cmd *exec.Cmd, write func([]byte)) {
    cmdReader, err := cmd.StdoutPipe()
    if err != nil {
        write([]byte(fmt.Sprintf("Error getting stdout pipe: %v", err)))
        return
    }
    cmd.Stderr = cmd.Stdout

    scanner := bufio.NewScanner(cmdReader)
    errCh := make(chan error)

    go func() {
        errCh <- cmd.Run()
    }()

    for scanner.Scan() {
        write(scanner.Bytes())
    }

    err = <-errCh
    if err != nil {
        write([]byte(err.Error()))
    }
}

这就是调用executewrite的方式。命令输出将作为服务器端事件发送到客户端。

execute(cmdInfo.cmd, func(data []byte) {
    fmt.Fprintf(w, "data: %s\n\n", data)
    flusher.Flush()
})

在* nix环境中运行容器时,似乎没有这个问题。问题可能出在Windows的Docker桌面上。

0 个答案:

没有答案