Home > Backend Development > Golang > How to Retrieve and Process Real-Time Output from Shell Commands in Go?

How to Retrieve and Process Real-Time Output from Shell Commands in Go?

Linda Hamilton
Release: 2024-12-11 04:40:14
Original
918 people have browsed it

How to Retrieve and Process Real-Time Output from Shell Commands in Go?

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"
Copy after login

)

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()
Copy after login

}

// 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)
}
Copy after login

}

// 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)
Copy after login

}

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!

source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Articles by Author
Popular Recommendations
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template