我怎样才能得到错误消息从一个执行命令链发出错误标准输出

问题描述:

在我的搜索中,我发现了很多如何检索一个单一的exec命令stdOut错误的例子,但我一直在努力与整体事物的链条。我怎样才能得到错误消息从一个执行命令链发出错误标准输出

在我的实际代码中,我有5个exec进程和一个由io管道连接的结果的文件写入。这是我去上的简化版本,在现实世界中从管道的标准输出作为下道工序的标准输入,直到我们遇到复制的最后文件的写:

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没有按排序顺序

从COMM过程,坐在那里的地方,但我从最后的错误捕捉看到的是简单的:我看到建议的标准输出像读

退出状态1

的例子这个:

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错误处理中读取管道中的错误,或者有更好的方法吗?

在去1.7,虽然我怀疑这个问题。

如果有人能指出我正确的方向,理想情况下举一个例子,这将不胜感激。

试试这个:

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