通过子进程

时间:2017-03-23 17:43:47

标签: python python-3.x pdf subprocess ghostscript

我有一个损坏的PDF,当我通过终端输入此命令时:

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

成功创建了一个新的(未损坏的)PDF文件(repaired_file.pdf)。但是,当我尝试从subprocess.call()或subprocess.Popen()中运行此命令时,命令失败:

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

必需的解决方案:

任何解决方案都会很棒,但由于已知的安全问题,我不喜欢在我的子流程语句中使用shell=True

我自己尝试解决问题的方法是:

  • 为方便起见,我在整个基本目录+所有文件上使用了chmod 777,以便我确定它不是权利问题。
  • 因为我知道有时需要使用子进程调用中使用的任何命令的完整路径,所以我也尝试了很多变体,从我在终端中使用的简单"gs"到完整"/usr/zsh", "/usr/local/bin/gs"。 1}}在子进程调用中但没有用。
  • 我对整个语法进行了三重检查(是的,我也尝试将整个命令包装在变量中并使用shlex.split(命令)来确保我的语法,所以我很确定它是不是语法问题。

任何帮助都表示赞赏!

1 个答案:

答案 0 :(得分:1)

您明确地将引号添加到路径中,因此gs会尝试查找路径以"开头和结尾的文件。没有惊喜它找不到它。假设您使用的是Linux或其他类Unix系统(*),在命令行中,引号是shell的进程,gs使用不带引号的参数调用。

只需使用:

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)

(*)Windows上的情况会有所不同