Reputation: 6968
I have the following piece of code which needs to be platform independent which isn't at the moment:
This works in windows to start the python script "pb_cli.py"
proc = subprocess.Popen(["python","pb_cli.py","get_token","60"], stdout=subprocess.PIPE, shell=True, cwd = '.',)
(result, err) = proc.communicate()
However - this does not seem to work in Linux. In Linux, I need to do this:
proc = subprocess.Popen(["python pb_cli.py get_token 60"], stdout=subprocess.PIPE, shell=True, cwd = '.',)
(result, err) = proc.communicate()
When I try to use the Linux version on windows, I get the following error:
C:\Users\Documents\Code\STAGE\cli>python move_users.py --input=users.txt --username --source_account=531 --destination_account=9
'"python pb_cli.py get_token 60"' is not recognized as an internal or external command, operable program or batch file.
When I try to use the Windows version on Linux, it just starts the interpretor.
Anybody have any idea on how to make this code uniform across platforms?
Upvotes: 4
Views: 977
Reputation: 880429
For any OS, when shell=False
(which it is by default), the first argument should be a list:
Popen(["python","pb_cli.py","get_token","60"], stdout=subprocess.PIPE)
When shell=True
, the first argument should be a string:
subprocess.Popen("python pb_cli.py get_token 60", shell=True, stdout=subprocess.PIPE)
PS. Try to avoid using shell=True
since it can be a security risk.
The actual rule is a bit more complicated. The docs say,
If passing a single string, either shell must be True (see below) or else the string must simply name the program to be executed without specifying any arguments.
which implies that you can pass a string when shell=False
as long at it is simply the name of the program to be executed. However, if you stick to the above rule, you won't go wrong.
Upvotes: 2