I am attempting to spawn a subprocess from Golang. The goal is to read and process the input line-by-line. Here is what I am trying to get working:
func readStuff(scanner *bufio.Scanner) {
for scanner.Scan() {
fmt.Println("Performed Scan")
fmt.Println(scanner.Text())
}
if err := scanner.Err(); err != nil {
fmt.Fprintln(os.Stderr, "reading standard input:", err)
}
}
func main() {
cmd := exec.Command("/usr/local/bin/pocketsphinx_continuous", "-inmic", "yes")
out, err := cmd.StdoutPipe()
err = cmd.Start()
checkError(err)
scanner := bufio.NewScanner(out)
fmt.Println("Scanner created")
defer cmd.Wait()
go readStuff(scanner)
}
In this example, "Scanner created" is printed, but nothing happens after that.
Running this command however does result in what I am expecting to be printed to :
/usr/local/bin/pocketsphinx_continuous -inmic yes 1>out.txt
And modifying the code to directly copy to stdout
works as well:
cmd := exec.Command("/usr/local/bin/pocketsphinx_continuous", "-inmic", "yes")
cmd.Stdout = os.Stdout
What am I missing that is keeping me from reading the output?
To capture the output of the subprocess. run method, use an additional argument named “capture_output=True”. You can individually access stdout and stderr values by using “output. stdout” and “output.
When subprocess. STDOUT is specified, the subprocess's standard error stream will be connected to the same pipe as the standard output stream. All other keyword arguments are passed to subprocess. Popen without interpretation, except for bufsize, universal_newlines and shell, which should not be specified at all.
This seems to work fine, and it works with go readStuff(scanner)
and also with just readStuff(scanner)
- I don't think that this usage actually calls for a goroutine, but don't know the actual context.:
package main
import (
"bufio"
"fmt"
"os"
"os/exec"
)
func readStuff(scanner *bufio.Scanner) {
for scanner.Scan() {
fmt.Println("Performed Scan")
fmt.Println(scanner.Text())
}
if err := scanner.Err(); err != nil {
fmt.Fprintln(os.Stderr, "reading standard input:", err)
}
}
func main() {
cmd := exec.Command("/Users/rfay/bin/junk.sh")
out, err := cmd.StdoutPipe()
err = cmd.Start()
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to start err=%v", err)
os.Exit(1)
}
scanner := bufio.NewScanner(out)
fmt.Println("Scanner created")
defer cmd.Wait()
go readStuff(scanner)
}
This is the junk.sh I used for testing.
#!/bin/bash
for i in `seq 1 10`;
do
echo $i
sleep 1
done
Seems you need not
go readStuff(scanner)
because of
cmd.Start()
do system fork itself so just
readStuff(scanner)
would be enough to my mind (not spawning gorouting for that)
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