我正在尝试在远程服务器上运行Python中的bash命令pdfcrack。这是我的代码:
bashCommand = "pdfcrack -f pdf123.pdf > myoutput.txt"
import subprocess
process = subprocess.Popen(bashCommand.split(), stdout=subprocess.PIPE)
output, error = process.communicate()
但是,我收到以下错误消息:
Non-option argument myoutput2.txt
Error: file > not found
有人可以看到我的错误吗?
答案 0 :(得分:1)
>
由shell解释,但在其他方式无效。
所以,这样可行(不要拆分,按原样使用):
process = subprocess.Popen(bashCommand, shell=True)
(stdout=subprocess.PIPE
并不常用,因为所有输出都被重定向到输出文件)
但是使用本机python可以更好地重定向到输出文件并将参数作为列表传递(如果需要,可以处理引用保护)
with open("myoutput.txt","w") as f:
process = subprocess.Popen(["pdfcrack","-f","pdf123.pdf"], stdout=subprocess.PIPE)
f.write(process.read())
process.wait()
答案 1 :(得分:1)
Popen
的第一个参数是包含命令名称及其参数的列表。但>
不是命令的参数;它是shell语法。你可以简单地将整行传递给Popen
并指示它使用shell来执行它:
process = subprocess.Popen(bashCommand, shell=True)
(请注意,由于您将命令的输出重定向到文件,因此没有理由将其标准输出设置为管道,因为没有什么可读的。)
更好的解决方案是让Python处理重定向。
process = subprocess.Popen(['pdfcrack', '-f', 'pdf123.pdf'], stdout=subprocess.PIPE)
with open('myoutput.txt', 'w') as fh:
for line in process.stdout:
fh.write(line)
# Do whatever else you want with line
另外,请勿使用str.split
代替shell的分词。像pdfcrack -f "foo bar.pdf"
这样的有效命令行会被拆分为不正确的列表['pdfcrack', '-f', '"foo', 'bar.pdf"']
,而不是正确的列表['pdfcrack', '-f', 'foo bar.pdf']
。
答案 2 :(得分:0)
你的错误是>
命令。
它不会将此视为重定向到文件,因为通常bash会执行此操作,现在您在不使用bash的情况下运行它。
如果您不想使用bash,请尝试使用shell=True
。然后你不必将命令分成列表。
subprocess.Popen("pdfcrack -f pdf123.pdf > myoutput.txt", shell=True)