【问题标题】:How can i get the error message from a chain of exec commands which emit errors to stdout如何从向标准输出发出错误的 exec 命令链中获取错误消息
【发布时间】:2017-04-02 16:29:09
【问题描述】:

在我的搜索中,我发现了许多关于如何为单个 exec 命令检索 stdOut 错误的示例,但我正在努力处理整个链条。

在我的实际代码中,我有 5 个 exec 进程和一个由 io 管道连接的结果文件写入。这是我所做工作的简化版本,在现实世界中,管道中的 stdOut 用作下一个进程的 stdIn,直到我们复制到最终文件写入为止:

    fileOut, err := os.Create(filePath)
    if err != nil {
        return fmt.Errorf("file create error: %s : %s", filePath, err)
    }

    writer := bufio.NewWriter(fileOut)
    defer writer .Flush()

    var exSortStdErr bytes.Buffer

    sort := exec.Command("sort", sortFlag)
    sort.Stderr = &sortStdErr
    sortStdOut, err := sort.StdoutPipe()

    if err != nil {
        return fmt.Errorf("sort pipe error: %s : %s", err, sortStdErr.String())
    }

    if err := sort.Start(); err != nil {
        return fmt.Errorf("sort start error : %s : %s", err, sortStdErr.String())
    }

    io.Copy(writer, sortStdOut)

    if err = sort.Wait(); err != nil {
        //catching error here
        return fmt.Errorf("sort wait error : %s: %s", err, sortStdErr.String())
    }

我已经简化了上述内容以说明这一点(因此不存在引发错误的实际进程),但我知道我遇到了一个错误,该错误与上述链中的 io 管道连接的 exec 进程之一相关但是有问题的过程将其错误放到stdOut,从我看到的终端重新创建

comm: 文件 1 没有排序

来自位于某处的通信进程,但我从最终错误捕获中看到的只是:

退出状态 1

我看到的示例建议从 stdOut 中读取如下内容:

var sortStdErr, sortStdOut bytes.Buffer
sort:= exec.Command("sort", sortFlag)
sort.Stdout = &sortStdOut
sort.Stderr = &sortStdErr

if err := sort.Run(); err !=nil {
    fmt.Println("error: %s %s", err, sortStdOut)
} 

这确实有效,但我不知道如何将结果与下一个流程结合起来。有没有办法从 cmd.wait 错误处理中读取管道中的错误,或者有更好的方法吗?

Go 1.7,虽然我怀疑这很重要。

如果有人能指出我正确的方向,最好举个例子,那将不胜感激。

【问题讨论】:

    标签: go pipe exec


    【解决方案1】:

    试试这个:

    var firstStdErr, firstStdOut bytes.Buffer
    firstCommand := exec.Command(
        "sort",
        sortFlag,
    )
    
    firstCommand.Stdout = &firstStdOut
    firstCommand.Stderr = &firstStdErr
    if err := firstCommand.Run(); err !=nil {
        fmt.Println("error: %s %s %s", err, firstStdErr, firstStdOut)
    } else{
        waitStatus := firstCommand.ProcessState.Sys().(syscall.WaitStatus)
        if waitStatus.ExitStatus() != 0 {
            fmt.Println("Non-zero exit code: " + strconv.Itoa(waitStatus.ExitStatus()))
        }
    }
    var secondStdErr, secondStdOut bytes.Buffer
    secondCommand := exec.Command(
        "command 2",
    )
    secondCommand.Stdin = &firstStdOut
    secondCommand.Stdout = &secondStdOut
    secondCommand.Stderr = &secondStdErr
    if err := secondCommand.Run(); err !=nil {
        fmt.Println("error: %s %s %s", err, secondStdErr, secondStdOut)
    }
    fileOut, err := os.Create(filePath)
    if err != nil {
        fmt.Errorf("file create error: %s : %s", filePath, err)
    }
    defer fileOut.Close()
    
    // sample writing to a file
    fileOut.Write(firstStdErr.Bytes())
    fileOut.Write(firstStdOut.Bytes())
    fileOut.Write(secondStdOut.Bytes())
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-26
      • 2018-08-08
      相关资源
      最近更新 更多