Using a Windows path within Python's subproces

2020-07-18 10:56发布

问题:

I started developing a small pdf to jpg script on a Windows 7 x64 machine with cygwin installed (Python 2.7). The following works perfectly:

import subprocess
filename = "test"
subprocess.check_output('gs -sDEVICE=jpeg -dPDFFitPage -g2800x3620 -o ' + filename + '-2800-%03d.jpg ' + filename + '.pdf', stderr=subprocess.STDOUT)

After pulling this project on my Windows 10 x64 non-Cygwin machine (Python 2.7), this code errors as it no longer recognizes "gs" as a built-in short for ghostscript. So I try the following:

import subprocess
filename = "test"
subprocess.check_output('C:\Program Files\gs\gs9.20\bin\gwin64c.exe -sDEVICE=jpeg -dPDFFitPage -g2800x3620 -o ' + filename + '-2800-%03d.jpg ' + filename + '.pdf', stderr=subprocess.STDOUT)

WindowsError: [Error 2] The system cannot find the file specified

Ok fine, I am a beginner and making some obvious mistake here. Also the "\b" characters in between .20\bin\ are highlighted ... indicating to me I somehow haven't made clear this is a single path.

Things I have also tried (separate runs):

subprocess.check_output(r'C:\Program Files\gs\gs9.20\bin\gwin64c.exe -sDEVICE=jpeg -dPDFFitPage -g2800x3620 -o ' + filename + '-2800-%03d.jpg ' + filename + '.pdf', stderr=subprocess.STDOUT')

subprocess.check_output("C:\Program Files\gs\gs9.20\bin\gwin64c.exe -sDEVICE=jpeg -dPDFFitPage -g2800x3620 -o ' + filename + '-2800-%03d.jpg ' + filename + '.pdf', stderr=subprocess.STDOUT/s", shell=True)

I have read: * How to use the dir/s command in Python? * How to execute a command prompt command from python * wrapping cmd.exe with subprocess * Python subprocess does not take correct arguments * wrapping cmd.exe with subprocess to no avail :( .

The error given always is:

Traceback (most recent call last):
File "C:/Python/Project/projectx/manual_conversion/manual_conversion.py", line 16, in <module>
subprocess.check_output(r'C:\Program Files\gs\gs9.20\bin\gwin64c.exe -sDEVICE=jpeg -dPDFFitPage -g2800x3620 -o ' + filename + '-2800-%03d.jpg ' + filename + '.pdf', stderr=subprocess.STDOUT)
File "C:\Python\Python 2.7.12\lib\subprocess.py", line 567, in check_output
process = Popen(stdout=PIPE, *popenargs, **kwargs)
File "C:\Python\Python 2.7.12\lib\subprocess.py", line 711, in __init__
errread, errwrite)
File "C:\Python\Python 2.7.12\lib\subprocess.py", line 959, in _execute_child
startupinfo)
WindowsError: [Error 2] The system cannot find the file specified

I fully understand this is rookie stuff + switching to unix would make my life easier - but in my corporate environment I don't fully have that option atm. Any help would be appreciated!

first question, point me to any changes if needed!

EDIT 1: I have also tried:

subprocess.check_output(r'C:\Program Files\gs\gs9.20\bin\gwin64c.exe -sDEVICE=jpeg -dPDFFitPage -g2800x3620 -o 2800-%03d.jpg test.pdf')

Since I thought maybe my variable concatenation was breaking the command ... but this again yields the same error.

EDIT 2: Passing the full argument as a list

subprocess.check_output([r'C:\Program Files\gs\gs9.20\bin\gswin64c.exe -sDEVICE=jpeg -dPDFFitPage -g2800x3620 -o 2800-%03d.jpg test.pdf'])

Yields the same error. But this:

subprocess.check_output([r'C:\Program Files\gs\gs9.20\bin\gswin64c.exe'])

Does start up ghostscript in Windows. Thank you @lit for making me try things, now the new problem is how to pass options to subprocess' check_output executable :) .

Still bothers me how easy it worked on a Windows system simply because it had cygwin installed that somehow modified cmd namespace to recognize "gs"...

回答1:

The path contains a space here Program Files. Typically, a space means end of the path. Using quotes " around the path tells the operating system not to consider the space as the end of the path but to take all the text in between the quotes as the path. So just add quotes:

subprocess.check_output([r'"C:\Program Files\gs\gs9.20\bin\gswin64c.exe" -sDEVICE=jpeg -dPDFFitPage -g2800x3620 -o 2800-%03d.jpg test.pdf'])