Skip to content

Instantly share code, notes, and snippets.

@mxschmitt
Last active April 18, 2024 21:48
Show Gist options
  • Save mxschmitt/6c07b5b97853f05455c3fdaf48b1a8b6 to your computer and use it in GitHub Desktop.
Save mxschmitt/6c07b5b97853f05455c3fdaf48b1a8b6 to your computer and use it in GitHub Desktop.
Golang example of cmd stderr / stdout merge to a single channel
@echo off
echo Stdout
echo Stderr 1>&2
package main
import (
"bufio"
"fmt"
"io"
"log"
"os/exec"
)
func main() {
cmd := exec.Command("cmd.bat")
stderr, err := cmd.StderrPipe()
if err != nil {
log.Fatalf("could not get stderr pipe: %v", err)
}
stdout, err := cmd.StdoutPipe()
if err != nil {
log.Fatalf("could not get stdout pipe: %v", err)
}
go func() {
merged := io.MultiReader(stderr, stdout)
scanner := bufio.NewScanner(merged)
for scanner.Scan() {
msg := scanner.Text()
fmt.Printf("msg: %s\n", msg)
}
}()
if err := cmd.Run(); err != nil {
log.Fatalf("could not run cmd: %v", err)
}
if err != nil {
log.Fatalf("could not wait for cmd: %v", err)
}
}
@watsoncj
Copy link

watsoncj commented Dec 15, 2021

Thanks for sharing this. Note that the implementation of io.MultiReader will not read from the second reader until the first reader is exhausted. As a result this approach is more of a concat than a merge.

https://go.dev/src/io/multi.go

To merge while maintaining write order, it’s possible to reassign.

cmdReader, err := cmd.StdoutPipe()
cmd.Stderr = cmd.Stdout

https://stackoverflow.com/a/35995372

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment