Reputation: 129
I am trying to run the bash command pdfcrack in Python on a remote server. This is my code:
bashCommand = "pdfcrack -f pdf123.pdf > myoutput.txt"
import subprocess
process = subprocess.Popen(bashCommand.split(), stdout=subprocess.PIPE)
output, error = process.communicate()
I, however, get the following error message:
Non-option argument myoutput2.txt
Error: file > not found
Can anybody see my mistake?
Upvotes: 0
Views: 191
Reputation: 140256
>
is interpreted by shell, but not valid otherwise.
So, that would work (don't split, use as-is):
process = subprocess.Popen(bashCommand, shell=True)
(and stdout=subprocess.PIPE
isn't useful since all output is redirected to the output file)
But it could be better with native python for redirection to output file and passing arguments as list (handles quote protection if needed)
with open("myoutput.txt","w") as f:
process = subprocess.Popen(["pdfcrack","-f","pdf123.pdf"], stdout=subprocess.PIPE)
f.write(process.read())
process.wait()
Upvotes: 1
Reputation: 531808
The first argument to Popen
is a list containing the command name and its arguments. >
is not an argument to the command, though; it is shell syntax. You could simply pass the entire line to Popen
and instruct it to use the shell to execute it:
process = subprocess.Popen(bashCommand, shell=True)
(Note that since you are redirecting the output of the command to a file, though, there is no reason to set its standard output to a pipe, because there will be nothing to read.)
A better solution, though, is to let Python handle the redirection.
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
Also, don't use str.split
as a replacement for the shell's word splitting. A valid command line like pdfcrack -f "foo bar.pdf"
would be split into the incorrect list ['pdfcrack', '-f', '"foo', 'bar.pdf"']
, rather than the correct list ['pdfcrack', '-f', 'foo bar.pdf']
.
Upvotes: 1
Reputation: 142814
Your mistake is >
in command.
It doesn't treat this as redirection to file because normally bash does it and now you run it without using bash.
Try with shell=True
if you whan to use bash. And then you don't have to split command into list.
subprocess.Popen("pdfcrack -f pdf123.pdf > myoutput.txt", shell=True)
Upvotes: 0