在服务器上运行bash命令

时间:2017-01-13 18:11:24

标签: python bash

我正在尝试在远程服务器上运行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

有人可以看到我的错误吗?

3 个答案:

答案 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)
相关问题