If I run echo a; echo b
in bash the result will be that both commands are run. However if I use subprocess then the first command is run, printing out the whole of the rest of the line. The code below echos a; echo b
instead of a b
, how do I get it to run both commands?
import subprocess, shlex def subprocess_cmd(command): process = subprocess.Popen(shlex.split(command), stdout=subprocess.PIPE) proc_stdout = process.communicate()[0].strip() print proc_stdout subprocess_cmd("echo a; echo b")
Run Multiple Commands at Once In Linux: You can use the | operator to concatenate two commands. The first command will list the files and folders in the directory, and the second command will print the output All the files and folders are listed.
Setting the shell argument to a true value causes subprocess to spawn an intermediate shell process, and tell it to run the command. In other words, using an intermediate shell means that variables, glob patterns, and other special shell features in the command string are processed before the command is run.
The subprocess module defines one class, Popen and a few wrapper functions that use that class. The constructor for Popen takes arguments to set up the new process so the parent can communicate with it via pipes. It provides all of the functionality of the other modules and functions it replaces, and more.
You have to use shell=True in subprocess and no shlex.split:
import subprocess command = "echo a; echo b" ret = subprocess.run(command, capture_output=True, shell=True) # before Python 3.7: # ret = subprocess.run(command, stdout=subprocess.PIPE, shell=True) print(ret.stdout.decode())
returns:
a b
I just stumbled on a situation where I needed to run a bunch of lines of bash code (not separated with semicolons) from within python. In this scenario the proposed solutions do not help. One approach would be to save a file and then run it with Popen
, but it wasn't possible in my situation.
What I ended up doing is something like:
commands = ''' echo "a" echo "b" echo "c" echo "d" ''' process = subprocess.Popen('/bin/bash', stdin=subprocess.PIPE, stdout=subprocess.PIPE) out, err = process.communicate(commands) print out
So I first create the child bash process and after I tell it what to execute. This approach removes the limitations of passing the command directly to the Popen
constructor.
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