我想使用Python的子进程模块将正则表达式传递给pdfgrep。代码执行时没有错误,但pdfgrep没有正确接收参数。测试pdf在cwd中并包含字符串' Mary Jane'。这是我的代码(Python 3.6):
import subprocess
filtered = ['[A-Z].+Jane'] # the list of regexes is shortened to one string, to keep the example simple.
for regex in filtered:
arg = 'pdfgrep -PrH ' + f"{regex}"
process_match = subprocess.run(arg, stdout=subprocess.PIPE, shell=True)
预期结果是process_match
将包含包含匹配项的CompletedProcess()
对象。
但相反,它会返回以下内容:
CompletedProcess(args="pdfgrep -PrH '[A-Z].+Jane'", returncode=127, stdout=b'')
在命令行中,调用相同的pdfgrep
命令可找到匹配的pdf。我可以在Ruby中使用以下代码轻松完成任务:
process_match = %x[pdfgrep -PrH "#{regex}"]
我是python的新手。在尝试将正则表达式传递给外部命令时,我出了什么问题?
答案 0 :(得分:3)
subprocess.run需要参数列表(不是字符串),例如
arg = ['pdfgrep', '-PrH', f"{regex}"]
而不是arg = 'pdfgrep -PrH' + f"{regex}"
修改强>
您在使用shell=True
时应该使用字符串的注释是正确的,但正如python子流程文档中所讨论的那样,可能存在安全隐患,并且它很少是绝对必要的,因此最好开发不使用外壳的习惯。
答案 1 :(得分:0)
以下代码按预期工作:
for regex in filtered:
arg = ['/usr/local/bin/pdfgrep', '-PrH', f"{regex}"]
process_match = subprocess.run(arg, stdout=subprocess.PIPE)
我的原始代码(至少)有两个问题。首先,我需要将命令作为列表传递给subprocess.run
,但为了实现这一点,我需要指定pdfgrep的完整路径。