douqie6454 2017-10-02 00:04
浏览 90

同时扫描stdout和stderr

I'm looking for a way to process both stdout and stderr simultaneously as one stream. For a stdout I can use:

cmd := exec.Command(command, flags...)
var wg sync.WaitGroup

stdout, err := cmd.StdoutPipe()
if err != nil {
    return fmt.Errorf("RunCommand: cmd.StdoutPipe(): %v", err)
}

if err := cmd.Start(); err != nil {
    return fmt.Errorf("RunCommand: cmd.Start(): %v", err)
}

scanner := bufio.NewScanner(stdout)
scanner.Split(ScanLinesR)
wg.Add(1)
go func() {
    for scanner.Scan() {
        text := scanner.Text()
        if strings.TrimSpace(text) != "" {
            DoWhateverYouNeedWithText(text)
        }
    }
    wg.Done()
}()

wg.Wait()

But how I add stderr to the same code?

  • 写回答

2条回答 默认 最新

  • doushi4956 2017-10-02 01:29
    关注

    As above commentors suggested I added 2 more goroutines (one for stderr, one for closing channel).

    var wg sync.WaitGroup
    
    stdout, err := cmd.StdoutPipe()
    if err != nil {
        return fmt.Errorf("RunCommand: cmd.StdoutPipe(): %v", err)
    }
    stderr, err := cmd.StderrPipe()
    if err != nil {
        return fmt.Errorf("RunCommand: cmd.StderrPipe(): %v", err)
    }
    
    if err := cmd.Start(); err != nil {
        return fmt.Errorf("RunCommand: cmd.Start(): %v", err)
    }
    
    outch := make(chan string, 10)
    
    scannerStdout := bufio.NewScanner(stdout)
    scannerStdout.Split(ScanLinesR)
    wg.Add(1)
    go func() {
        for scannerStdout.Scan() {
            text := scannerStdout.Text()
            if strings.TrimSpace(text) != "" {
                outch <- text
            }
        }
        wg.Done()
    }()
    scannerStderr := bufio.NewScanner(stderr)
    scannerStderr.Split(ScanLinesR)
    wg.Add(1)
    go func() {
        for scannerStderr.Scan() {
            text := scannerStderr.Text()
            if strings.TrimSpace(text) != "" {
                outch <- text
            }
        }
        wg.Done()
    }()
    
    go func() {
        wg.Wait()
        close(outch)
    }()
    
    for t := range outch {
        DoWhateverYouNeedWithText(t)
    }
    
    评论

报告相同问题?

悬赏问题

  • ¥15 科来模拟ARP欺骗困惑求解
  • ¥100 iOS开发关于快捷指令截屏后如何将截屏(或从截屏中提取出的文本)回传给本应用并打开指定页面
  • ¥15 unity连接Sqlserver
  • ¥15 图中这种约束条件lingo该怎么表示出来
  • ¥15 VSCode里的Prettier如何实现等式赋值后的对齐效果?
  • ¥15 流式socket文件传输答疑
  • ¥20 keepalive配置业务服务双机单活的方法。业务服务一定是要双机单活的方式
  • ¥50 关于多次提交POST数据后,无法获取到POST数据参数的问题
  • ¥15 win10,这种情况怎么办
  • ¥15 如何在配置使用Prettier的VSCode中通过Better Align插件来对齐等式?(相关搜索:格式化)