Real-Time Output Retrieval in Go for Shell Commands
In Golang, the os/exec package provides the means to execute shell commands. However, when these commands return real-time output or progress updates, it becomes necessary to retrieve and process that information dynamically. Here's how to achieve this:
For capturing and processing the real-time output of a shell command in Go, consider the following approach:
package main</p> <p>import (</p> <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">"bufio" "fmt" "io" "os" "os/exec" "strings"
)
func main() {
cmdName := "ffmpeg -i t.webm -acodec aac -vcodec libx264 cmd1.mp4" cmdArgs := strings.Fields(cmdName) cmd := exec.Command(cmdArgs[0], cmdArgs[1:len(cmdArgs)]...) stderr, _ := cmd.StderrPipe() cmd.Start() go printProgress(stderr) cmd.Wait()
}
// to print the processed information when stderr gets a new line
func printProgress(stderr io.ReadCloser) {
r := bufio.NewReader(stderr) for { line, _, err := r.ReadLine() if err != nil { fmt.Println("error in reading from stderr:", err) break } // Process the line (e.g., extract the progress percentage) percentage, err := extractPercentage(string(line)) if err != nil { fmt.Println("error in extracting percentage:", err) continue } // Print the updated progress ratio fmt.Printf("%s%%", percentage) }
}
// extractPercentage parses the line of ffmpeg output and returns the progress percentage.
// This assumes the output format in the question (e.g., "frame=... size=... time=... bitrate=...")
func extractPercentage(line string) (string, error) {
parts := strings.Split(line, " ") if len(parts) < 4 { return "", fmt.Errorf("invalid line format: %s", line) } size := parts[2] sizeUnits := []string{"B", "kB", "MB", "GB", "TB", "PB"} for i, unit := range sizeUnits { if strings.HasSuffix(size, unit) { factor := float64(1 << (10 * i)) sizeBytes, err := strconv.ParseFloat(strings.TrimSuffix(size, unit), 64) if err != nil { return "", err } percentage := (sizeBytes / factor) / 100 return strconv.FormatFloat(percentage, 'f', 2, 64), nil } } return "", fmt.Errorf("unknown size unit: %s", size)
}
This approach uses pipes to retrieve the real-time output from the stderr stream of the command. It continuously reads and processes the output, extracting the progress information and printing it dynamically. Note that the extractPercentage function in this example extracts the percentage from the ffmpeg output, assuming the specific format mentioned in the question. This may need to be adjusted based on the specific output format of your shell command.
The above is the detailed content of How to Retrieve and Process Real-Time Output from Shell Commands in Go?. For more information, please follow other related articles on the PHP Chinese website!