Выполнение команды bash на сервере

89
7

Я пытаюсь запустить команду bash pdfcrack в Python на удаленном сервере. Это мой код:

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

Может ли кто-нибудь увидеть мою ошибку?

спросил(а) 2017-01-13T21:11:00+03:00 3 года, 8 месяцев назад
1
Решение
58

Первый аргумент Popen - это список, содержащий имя команды и ее аргументы. > не является аргументом команды; это синтаксис оболочки. Вы можете просто передать всю строку в Popen и дать ей возможность использовать оболочку для ее выполнения:

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 в качестве замены для разделения слова оболочки. Правильная командная строка, такая как pdfcrack -f "foo bar.pdf", будет разбита на неправильный список ['pdfcrack', '-f', '"foo', 'bar.pdf"'], а не на правильную list ['pdfcrack', '-f', 'foo bar.pdf'].

ответил(а) 2017-01-13T21:20:00+03:00 3 года, 8 месяцев назад
57

> интерпретируется оболочкой, но недействительно в противном случае.

Таким образом, это будет работать (не разделить, использовать как есть):

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()

ответил(а) 2017-01-13T21:16:00+03:00 3 года, 8 месяцев назад
40

Ваша ошибка > в команде.

Он не относится к этому как перенаправление к файлу, потому что обычно bash делает это, и теперь вы запускаете его без использования bash.

Попробуйте с shell=True если вы хотите использовать bash. И тогда вам не нужно разделить команду на список.

subprocess.Popen("pdfcrack -f pdf123.pdf > myoutput.txt", shell=True)

ответил(а) 2017-01-13T21:18:00+03:00 3 года, 8 месяцев назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема