我如何从执行命令链中获取错误消息,这些执行命令向stdout发出错误

In my searches I've found many examples of how to retrieve the stdOut error for a single exec command but I'm struggling with a whole chain of the things.

In my actual code I have 5 exec processes and a file write of the result all joined by io pipes. This is a simplified version of what I have going on, in real world the stdOut from the pipe is used as the stdIn of the next process until we copy across for the final file write :

    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())
    }

I have simplified the above to illustrate the point (so the actual process throwing the error isn't there), but I know that Im getting an error related to one of the exec processes connected by io pipes in a chain like above but the process in question puts its error to stdOut, recreating from the terminal I see

comm: file 1 is not in sorted order

from a comm process which sits in there somewhere but what i see from the final error catch is simply:

exit status 1

the examples I saw suggested reading from stdOut something like this:

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)
} 

And this does indeed work, but I don't know how to marry this up with piping the results to the next process. Is there a way to read the error off the pipe from within the cmd.wait error handling or is there a better approach?

On go 1.7, though i doubt that matters.

If someone could point me in the right direction, ideally with an example, that would be much appreciated.

Try this:

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())