Last active
April 18, 2024 21:48
-
-
Save mxschmitt/6c07b5b97853f05455c3fdaf48b1a8b6 to your computer and use it in GitHub Desktop.
Golang example of cmd stderr / stdout merge to a single channel
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@echo off | |
echo Stdout | |
echo Stderr 1>&2 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | |
} | |
} |
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
the output: