SB87 SB87 -4 years ago 160
Python Question

GhostScript fails to create output file when called via subprocess

I have a corrupted PDF and when I enter this command via terminal:

gs -o "/Path/to/required/repaired_file.pdf" -sDEVICE=pdfwrite -dPDFSETTINGS=/prepress "/Path/to/required/corrupted_file.pdf"


A new (non-corrupted) PDF file (repaired_file.pdf) is successfully created. However, when I try to run this command from within subprocess.call() or subprocess.Popen() the command fails:

Python 3.4.4 (v3.4.4:737efcadf5a6, Dec 19 2015, 20:38:52)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> import subprocess
>>> subprocess.call(["/usr/local/bin/gs", "-o", "\"/Path/to/required/repaired_file.pdf\"", "-sDEVICE=pdfwrite", "-dPDFSETTINGS=/prepress", "\"/Path/to/required/corrupted_file.pdf\""], stderr=sys.stdout)
GPL Ghostscript 9.20 (2016-09-26)
Copyright (C) 2016 Artifex Software, Inc. All rights reserved.
This software comes with NO WARRANTY: see the file PUBLIC for details.
GPL Ghostscript 9.20: **** Could not open the file "/Path/to/required/repaired_file.pdf" .
**** Unable to open the initial device, quitting.
1


Required solution:

Any solution would be great, however I do not like to use
shell=True
in my subprocess statements due to the known security issues that brings.

My own attempts to solve it have been:


  • For convenience sake I have used
    chmod 777
    on the entire base directory + all it's files so that I am sure it is not a rights issue.

  • Since I know that it is sometimes necessary to use the full paths of any command used within a subprocess call I have also tried many variants ranging from the simple
    "gs"
    that I use in my Terminal to the full
    "/usr/zsh", "/usr/local/bin/gs"
    within the subprocess call but to no avail.

  • I have triple-checked my syntax overall (and yes, I also tried to wrap my entire command in a variable and use shlex.split(command) to be double-sure of my syntax, so I am pretty sure it is not a syntax problem.



Any help's appreciated!

Answer Source

You explicitely add the quotes to the path, so gs tries to find a file whose path starts and end with a ". Not surprizinly it cannot find it. Assuming you are using a Linux or other Unix-like sytem(*), in the command line, the quotes are processes by the shell and gs is called with an unquoted parameter.

Just use:

subprocess.call(["/usr/local/bin/gs", "-o", "/Path/to/required/repaired_file.pdf", 
    "-sDEVICE=pdfwrite", "-dPDFSETTINGS=/prepress", "/Path/to/required/corrupted_file.pdf"],
    stderr=sys.stdout)

(*)Things would be different on Windows

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download