Reputation: 311
I have this piece of code that executes well:
import subprocess
exe_cmd = subprocess.Popen(["ls", "-al"], stdout=subprocess.PIPE)
output, err = exe_cmd.communicate()
print output
And I have another piece where I assign the command to a variable and then pass it as argument. But in this case it fails. Why?
import subprocess
#Here I assign the command to a variable.
cmd = "ls -al"
exe_cmd = subprocess.Popen(cmd, stdout=subprocess.PIPE)
output, err = exe_cmd.communicate()
print output
Upvotes: 1
Views: 90
Reputation: 10585
The first argument to Popen
is a list of arguments, in your first example you are passing it
["ls", "-al"]
in your second example you are passing it a string "ls -al".
You could change the code assigning ["ls", "-al"]
to cmd
.
You can also use shlex.split
to parse the string and get the list to pass to Popen
Upvotes: 1
Reputation: 14490
If you want to use a string as the first argument to Popen, you will need to set shell=True
in the call. Otherwise it tries to find an executable with the full string and run that, which of course does not exist in this case.
Upvotes: 3
Reputation: 52071
Your cmd variable should be
cmd = ["ls","-al" ]
This is made clear in the documentation
On Unix, if args is a string, the string is interpreted as the name or path of the program to execute. However, this can only be done if not passing arguments to the program.
So you need to set shell=True
On Unix with
shell=True
, the shell defaults to /bin/sh. If args is a string, the string specifies the command to execute through the shell. This means that the string must be formatted exactly as it would be when typed at the shell prompt. This includes, for example, quoting or backslash escaping filenames with spaces in them. If args is a sequence, the first item specifies the command string, and any additional items will be treated as additional arguments to the shell itself.
(emphasis mine)
Upvotes: 2