I have the following bash script bash_loop.sh
that prints 1 to 10 and sleep 3 s in between.
#!/bin/bash
# Basic while loop
counter=1
while [ $counter -le 10 ]
do
echo $counter
((counter++))
sleep 3
done
echo All done
Right now, I have my go code as follow:
burstingScript := "bash_loop.sh"
cmd := exec.Command("/bin/sh", burstingScript)
var out bytes.Buffer
cmd.Stdout = &out
if err := cmd.Run(); err != nil {
fmt.Println("An error has occurred..")
log.Fatal(err)
}
fmt.Println(out.String())
However, this only print out everything after the cmd finish running after 30s, instead of print things as they become available.
So my question is that if I can print each number while the bash script is still running instead of printing everything all together after the bash script finishes execution.
P.S.1: In the real use case, I have to process the output of bash script in realtime, instead of simply printing things out to os.Stdout
, so I am wondering if there's any command poll()
interface or equivalence in go.
P.S.2:In the real use case, I want to detach from the child process as soon as I find interesting message. For example, after I read 3, I want my function return 3 immediately and not wait for the rest of output anymore, though I still want the child process (the bash script) itself to be up and running.
P.S.3: In python, I would do something like this
cmd = "./bash_loop.sh"
p = subprocess.Popen(cmd, shell=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
result = {}
while True:
out = p.stdout.readline()
if out == '' and p.poll() != None:
break
if out != '':
#process(out)
sys.stdout.write(out)
sys.stdout.flush()
P.S.4: Now I have evolved my go snippet to follow. Will the child become a zombie if I return before the command finishes running?
burstingScript := path.Join(rootDir, "bash_loop.sh")
cmd := exec.Command("/bin/sh", burstingScript)
stdout, _ := cmd.StdoutPipe()
cmd.Start()
scanner := bufio.NewScanner(stdout)
for scanner.Scan() {
m := scanner.Text()
fmt.Println(m)
//if m=="3" {
// return process(m)
//}
}
cmd.Wait()
Set the command output to stdout:
cmd.Stdout = os.Stdout
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With