Passing Variables to subprocess.Popen: Why It Doesn't Work with Arguments in Lists
When using subprocess.Popen to call another Python script, you may encounter issues passing arguments stored in variables. This can occur when you attempt to execute a command like the following:
p = subprocess.Popen( ["python mytool.py -a ", servers[server]['address'], "-x", servers[server]['port'], "-p", servers[server]['pass'], "some additional command"], shell=True, stdout=subprocess.PIPE )
The Problem:
The problem arises because of the use of shell=True. When this flag is enabled, the arguments passed to Popen() are handled differently on Unix systems. The shell interprets the arguments as a single command string, which can lead to unexpected behavior.
The Solution:
To resolve this issue, drop the use of shell=True. Instead, create a list of arguments directly and pass it to Popen(). Here's an example:
import sys from subprocess import Popen, PIPE # Populate list of arguments args = ["mytool.py"] for opt, optname in zip("-a -x -p".split(), "address port pass".split()): args.extend([opt, str(servers[server][optname])]) args.extend("some additional command".split()) # Run script p = Popen([sys.executable or 'python'] + args, stdout=PIPE) # ... Use p.stdout here p.stdout.close() p.wait()
By removing shell=True and constructing the arguments list manually, you ensure that the variables are correctly passed to the called script.
Security Caution:
It's important to note that passing shell=True for commands involving external input can pose a security risk, as mentioned in the subprocess documentation. If you handle user-provided input in your script, it's strongly recommended to avoid using shell=True to prevent potential vulnerabilities.
The above is the detailed content of Why Doesn\'t `subprocess.Popen` Work with Variable Arguments in Lists When `shell=True`?. For more information, please follow other related articles on the PHP Chinese website!