Skip to content

Instantly share code, notes, and snippets.

@hivefans
Last active September 15, 2023 05:59
Show Gist options
  • Star 52 You must be signed in to star a gist
  • Fork 13 You must be signed in to fork a gist
  • Save hivefans/ffeaf3964924c943dd7ed83b406bbdea to your computer and use it in GitHub Desktop.
Save hivefans/ffeaf3964924c943dd7ed83b406bbdea to your computer and use it in GitHub Desktop.
get the realtime output for a shell command in golang|-|{"files":{"shell_output.go":{"env":"plain"}},"tag":"bigdata"}
package main
import (
"bufio"
"fmt"
"io"
"os"
"os/exec"
"strings"
)
func main() {
cmdName := "ping 127.0.0.1"
cmdArgs := strings.Fields(cmdName)
cmd := exec.Command(cmdArgs[0], cmdArgs[1:len(cmdArgs)]...)
stdout, _ := cmd.StdoutPipe()
cmd.Start()
oneByte := make([]byte, 100)
num := 1
for {
_, err := stdout.Read(oneByte)
if err != nil {
fmt.Printf(err.Error())
break
}
r := bufio.NewReader(stdout)
line, _, _ := r.ReadLine()
fmt.Println(string(line))
num = num + 1
if num > 3 {
os.Exit(0)
}
}
cmd.Wait()
}
@nullmastermind
Copy link

nice work 👍 thanks

@swallowstalker
Copy link

nice, it really helps 👍

@shri3k
Copy link

shri3k commented Dec 2, 2019

For people coming from google - I revised a bit.

package main

import (
  "bufio"
  "os"
  "os/exec"
  "fmt"
  "log"
)

func main() {
  cmd := exec.Command("ping", "127.0.0.1")
  stdout, err := cmd.StdoutPipe()
  if err != nil {
    log.Fatal(err)
  }
  cmd.Start()

  buf := bufio.NewReader(stdout) // Notice that this is not in a loop
  num := 1
  for {
    line, _, _ := buf.ReadLine()
    if num > 3 {
      os.Exit(0)
    }
    num += 1
    fmt.Println(string(line))
  }
}

@krisztianodor
Copy link

You guys are the best!!! )

@hostbet
Copy link

hostbet commented May 1, 2021

Hello Sir, i want to run some curl bash scripts via golang want to show that script’s realtime output to the user.
for example,
i want to run
curl -Lso- bench.sh | bash
in golang and show realtime output to the user, how can i do this?

actually, i want to run some bash scripts and some binary files via golang and show the output to the user (realtime output) if read line by line and show to user then also OK but output should show to user in fast time
not like bash script executed and after execution output will show, i don’t want like that.
the bash script installs library and packages so it may take some time so that i want to show real time output of the bash script to user.

@smc181002
Copy link

For people coming from google - I revised a bit.

package main

import (
  "bufio"
  "os"
  "os/exec"
  "fmt"
  "log"
)

func main() {
  cmd := exec.Command("ping", "127.0.0.1")
  stdout, err := cmd.StdoutPipe()
  if err != nil {
    log.Fatal(err)
  }
  cmd.Start()

  buf := bufio.NewReader(stdout) // Notice that this is not in a loop
  num := 1
  for {
    line, _, _ := buf.ReadLine()
    if num > 3 {
      os.Exit(0)
    }
    num += 1
    fmt.Println(string(line))
  }
}

when I ran this, the ping command is stopping after an interval of time.
I use windows and ping in windows pings 4 times as default similar to ping -c4 127.0.0.1
but is there a way where we can get the return value of the command and stop the for loop?

@MiranDaniel
Copy link

Still up to date, March 21 2022

@Masternetworks
Copy link

Nice !

@cwbriscoe
Copy link

Here is another example that I made based on the code posted above:

func RunCmd(ctx context.Context, cmdstr string) error {
	args := strings.Fields(cmdstr)
	cmd := exec.CommandContext(ctx, args[0], args[1:]...)

	stdout, err := cmd.StdoutPipe()
	if err != nil {
		return err
	}

	var wg sync.WaitGroup
	wg.Add(1)

	scanner := bufio.NewScanner(stdout)
	go func() {
		for scanner.Scan() {
			log.Printf("out: %s", scanner.Text())
		}
		wg.Done()
	}()

	if err = cmd.Start(); err != nil {
		return err
	}

	wg.Wait()

	return cmd.Wait()
}

@joseluis10101
Copy link

Maybe you should use multiwritter:

cmd.Stdout = io.MultiWriter(os.Stdout, &stdout) cmd.Stderr = io.MultiWriter(os.Stderr, &stderr)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment