fume_hood_geologist
fume_hood_geologist

Reputation: 125

Using subprocess to open a cmd to run a Python function but having issues with whitespaces and double quotations

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

Answers (1)

Charles Duffy
Charles Duffy

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

Related Questions