Note: checking of all errors, fixed -u
flag, use of bufio to read a line, and Wait to wait for end of process.
import(
"bufio"
"fmt"
"log"
"os/exec"
)
func main() {
c: = exec.Command("python", "-u", "add.py")
si,
err: = c.StdinPipe()
if err != nil {
log.Fatal(err)
}
so,
err: = c.StdoutPipe()
if err != nil {
log.Fatal(err)
}
reader: = bufio.NewReader(so)
err = c.Start()
if err != nil {
log.Fatal(err)
}
// Now do some maths
for i: = 0;i < 10;i++{
sum: = fmt.Sprintf("2+%d\n", i)
_,
err = si.Write([] byte(sum))
if err != nil {
log.Fatal(err)
}
answer,
err: = reader.ReadString('\n')
if err != nil {
log.Fatal(err)
}
fmt.Printf("Answer to %q is %q\n", sum, answer)
}
// Close the input and wait for exit
si.Close()
so.Close()
c.Wait()
}
Which produces
Answer to "2+0\n"
is "2\n"
Answer to "2+1\n"
is "3\n"
Answer to "2+2\n"
is "4\n"
Answer to "2+3\n"
is "5\n"
Answer to "2+4\n"
is "6\n"
Answer to "2+5\n"
is "7\n"
Answer to "2+6\n"
is "8\n"
Answer to "2+7\n"
is "9\n"
Answer to "2+8\n"
is "10\n"
Answer to "2+9\n"
is "11\n"
The input argument is passed to Popen.communicate() and thus to the subprocess’s stdin. If used it must be a byte sequence, or a string if encoding or errors is specified or text is true. When used, the internal Popen object is automatically created with stdin=PIPE, and the stdin argument may not be used as well.,Special value that can be used as the stdin, stdout or stderr argument to Popen and indicates that a pipe to the standard stream should be opened. Most useful with Popen.communicate().,On Windows, an args sequence is converted to a string that can be parsed using the following rules (which correspond to the rules used by the MS C runtime):,The recommended approach to invoking subprocesses is to use the run() function for all use cases it can handle. For more advanced use cases, the underlying Popen interface can be used directly.
os.system os.spawn *
>>> subprocess.run(["ls", "-l"]) # doesn 't capture output CompletedProcess(args = ['ls', '-l'], returncode = 0) >>> subprocess.run("exit 1", shell = True, check = True) Traceback(most recent call last): ... subprocess.CalledProcessError: Command 'exit 1' returned non - zero exit status 1 >>> subprocess.run(["ls", "-l", "/dev/null"], capture_output = True) CompletedProcess(args = ['ls', '-l', '/dev/null'], returncode = 0, stdout = b 'crw-rw-rw- 1 root root 1, 3 Jan 23 16:23 /dev/null\n', stderr = b '')
Popen(["/usr/bin/git", "commit", "-m", "Fixes a bug."])
>>> import shlex, subprocess >>> command_line = input() / bin / vikings - input eggs.txt - output "spam spam.txt" - cmd "echo '$MONEY'" >>> args = shlex.split(command_line) >>> print(args)['/bin/vikings', '-input', 'eggs.txt', '-output', 'spam spam.txt', '-cmd', "echo '$MONEY'"] >>> p = subprocess.Popen(args) # Success!
Popen(['/bin/sh', '-c', args[0], args[1], ...])
with Popen(["ifconfig"], stdout = PIPE) as proc:
log.write(proc.stdout.read())
The communicate() method only reads data from stdout and stderr, until end-of-file is reached. So, after all the messages have been printed, if we call communicate() again we get an error:, Because a subprocess is independent, it executes concurrently with the original process. That is, the process that created the subprocess can go on to work on other things while the subprocess carries out its own work behind the scenes.,Note that the communicate() method returns a tuple (stdoutdata, stderrdata) : ('"Hello world!"\n' ,None). If we don't include stdout=subprocess.PIPE or stderr=subprocess.PIPE in the Popen call, we'll just get None back.,Additionally, stderr can be STDOUT, which indicates that the stderr data from the child process should be captured into the same file handle as for stdout.
Popen(['/bin/sh', '-c', args[0], args[1], ...])