How to Retrieve Realtime Output and Print Processed Information from a Shell Command in Golang
In this guide, we'll focus on a specific scenario where we execute a shell command that produces output in real time, such as ffmpeg. We aim to retrieve this output steadily and print processed information based on the data it provides.
Let's break down the original code and explain the issue:
package main import ( "bufio" "fmt" "io" "os" "os/exec" "strings" ) func main() { // ... stdout, _ := cmd.StdoutPipe() cmd.Start() go print(stdout) cmd.Wait() } func print(stdout io.ReadCloser) { // ... }
The issue lies in assuming the output will be sent to stdout, but in reality, ffmpeg sends diagnostic messages to stderr instead. To capture the desired output, we need to pipe the stderr stream. Here's a revised code that addresses this:
func main() { // ... stderr, _ := cmd.StderrPipe() cmd.Start() scanner := bufio.NewScanner(stderr) scanner.Split(bufio.ScanWords) for scanner.Scan() { m := scanner.Text() fmt.Println(m) } cmd.Wait() }
Now, the code reads from the stderr pipe and prints the words it receives. This ensures that we capture and display the diagnostic messages generated by ffmpeg.
For instance, if ffmpeg's progress bar looks like this:
frame= 101 fps=0.0 q=28.0 size= 91kB time=00:00:04.13 bitrate= 181.2kbits/ frame= 169 fps=168 q=28.0 size= 227kB time=00:00:06.82 bitrate= 272.6kbits/ frame= 231 fps=153 q=28.0 size= 348kB time=00:00:09.31 bitrate= 306.3kbits/ frame= 282 fps=140 q=28.0 size= 499kB time=00:00:11.33 bitrate= 360.8kbits/
Our code will capture and print these words line by line:
frame= 101 fps= 0.0 q= 28.0 size= 91kB time= 00:00:04.13 bitrate= 181.2kbits/ ... (and so on)
You can then use these words to parse the relevant information and update your progress accordingly.
The above is the detailed content of How to Capture and Print Realtime Output from a Shell Command's Standard Error in Golang?. For more information, please follow other related articles on the PHP Chinese website!