Reputation: 125
I need to address a very specific workflow where a function generates locks that are tied to the Python shell session. As a result, I'm trying to use subprocess to run that function in a completely separate cmd session.
I have a command that works in cmd:
"C:\Program Files\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\python.exe" -c "import sys; sys.path.insert(1, r'\\...\my_script_directory');import my_script; my_script.my_function('param 1', 'param 2')"
But when I try to execute it in subprocess.Popen, it keeps running into issues with the double quotations.
If I pass that cmd as a string into subprocess.Popen:
subprocess.Popen(cmd.exe c "C:\Program Files\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\python.exe" -c "import sys; sys.path.insert(1, r'\\...\my_script_directory');import my_script; my_script.my_function('param 1', 'param 2')")
then I get the error: 'C:\Program' is not recognized as an internal or external command, operable program or batch file.
If I add additional quotations like so:
subprocess.Popen(cmd.exe /c """"C:\Program Files\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\python.exe"""" -c """"import sys; sys.path.insert(1, r'\\...\my_script_directory');import my_script; my_script.my_function('param 1', 'param 2')"""")
then I get the error: The system cannot find the path specified.
I'm currently at a place where I can run Python code that has no spaces if I omit the quotations entirely
subprocess.Popen(cmd.exe /c "C:\Program Files\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\python.exe" -c print(1+1))
which successfully returns 2
Does subprocess.Popen and/or cmd.exe handle quotations for commands to an executable differently? I've tried multiple escape characters for spaces as well, but can't get it to work.
Upvotes: 0
Views: 39
Reputation: 295698
The right way to do this is to pass an argv array instead of a string. On UNIXy operating systems that means no quoting and escaping is necessary at all, since the native way arguments are passed is as an array of strings (an "argument vector", hence sys.argv
, and the conventional argv
argument to main
). On Windows, quoting is still necessary, but Python will generate quoting that works correctly for any program that doesn't override libc's default argument parsing.
python_exe = r'C:\Program Files\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\python.exe'
script = r'''
import sys
sys.path.insert(1, r'\\...\my_script_directory')
import my_script
my_script.my_function('param 1', 'param 2')
'''
subprocess.run([python_exe, '-c', script])
Upvotes: 1