Выполнение команды bash на сервере
Я пытаюсь запустить команду 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
Может ли кто-нибудь увидеть мою ошибку?
Первый аргумент 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']
.
>
интерпретируется оболочкой, но недействительно в противном случае.
Таким образом, это будет работать (не разделить, использовать как есть):
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()
Ваша ошибка >
в команде.
Он не относится к этому как перенаправление к файлу, потому что обычно bash делает это, и теперь вы запускаете его без использования bash.
Попробуйте с shell=True
если вы хотите использовать bash. И тогда вам не нужно разделить команду на список.
subprocess.Popen("pdfcrack -f pdf123.pdf > myoutput.txt", shell=True)