Home > Backend Development > Golang > How to Stream Command Output in Real-Time Using Go?

How to Stream Command Output in Real-Time Using Go?

Mary-Kate Olsen
Release: 2024-11-22 00:04:17
Original
973 people have browsed it

How to Stream Command Output in Real-Time Using Go?

Streaming Command Output Online

Consider the following code that executes a command and captures its output:

cmdParams := [][]string{
    {filepath.Join(dir, path), "npm", "install"},
    {filepath.Join(pdir, n.path), "gulp"},
}
for _, cp := range cmdParams {
    log.Printf("Starting %s in folder %s...", cp[1:], cp[0])
    cmd := exec.Command(cp[1], cp[2:]...)
    cmd.Dir = cp[0]
    // Wait to finish, get output:
    out, err := cmd.Output()
    if err != nil {
        log.Printf("Error running %s: %v\n", cp[1:], err)
        return
    }
    log.Println("Finished %s, output: %s", cp[1:], out)
}
Copy after login

This code captures the complete output of the command and prints it only after the command finishes execution. However, there is a need to stream the output in real-time.

To achieve live output streaming, we can modify the code as follows:

cmdParams := [][]string{
    {filepath.Join(dir, path), "npm", "install"},
    {filepath.Join(pdir, n.path), "gulp"},
}
for _, cp := range cmdParams {
    log.Printf("Starting %s in folder %s...", cp[1:], cp[0])
    cmd := exec.Command(cp[1], cp[2:]...)
    cmd.Dir = cp[0]

    stdout, err := cmd.StdoutPipe()
    if err != nil {
        log.Printf("%s cmd.StdoutPipe() error: %v\n", cp[1:], err)
        return
    }
    // Start command:
    if err = cmd.Start(); err != nil {
        log.Printf("%s start error: %v\n", cp[1:], err)
        return
    }

    // Stream command output:
    scanner := bufio.NewScanner(stdout)
    scanner.Split(bufio.ScanRunes)
    for scanner.Scan() {
        fmt.Print(scanner.Text())
    }
    if scanner.Err() != nil {
        log.Printf("Reading %s stdout error: %v\n", cp[1:], err)
        return
    }

    // Get execution success or failure:
    if err = cmd.Wait(); err != nil {
        log.Printf("Error running %s: %v\n", cp[1:], err)
        return
    }
    log.Printf("Finished %s", cp[1:])
}
Copy after login

Here's an explanation of the changes:

  • cmd.StdoutPipe() creates a pipe for reading the command's standard output.
  • cmd.Start() starts the command in the background.
  • bufio.NewScanner(stdout) creates a scanner for reading from the stdout pipe.
  • scanner.Split(bufio.ScanRunes) sets the scanner to read by runes, providing live streaming.
  • The scanner's Scan() loop continuously reads and prints each rune (character) produced by the command.
  • After the loop finishes (the command writing to stdout has finished), scanner.Err() checks for any errors.
  • cmd.Wait() waits for the command to finish and checks for errors.
  • The final log.Println() statement logs the command's completion.

The above is the detailed content of How to Stream Command Output in Real-Time Using 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 Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template