Reputation: 27
I want to call a subprocess to backup mysql database. A command line which ran fine in the terminal (and created a file named mydatabase.sql) is:
mysqldump -uroot -ppassword --add-drop-database --database mydatabase > mydatabase.sql
Now the code to be ran by python to call a subprocess:
args = shlex.split('mysqldump -uroot -ppassword --add-drop-database --database mydatabase > mydatabase.sql')
subprocess.check_call(args)
The exeption is raised (no file created):
Traceback (most recent call last):
File "<pyshell#29>", line 1, in <module>
subprocess.check_call(args)
File "/usr/lib/python3.2/subprocess.py", line 485, in check_call
raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['mysqldump', >'-uroot', '-ppassword', '--add-drop-database', '--database', >'mydatabase', '>', 'mydatabase.sql']' returned non-zero exit status 2
I have tried different ways, but they still don't work:
args = shlex.split('/opt/lampp/bin/mysqldump -uroot -ppassword --add-drop-database --database mydatabase > mydatabase.sql')
subprocess.check_call(args)
or
args = shlex.split('/opt/lampp/bin/mysqldump -uroot -ppassword --add-drop-database --database mydatabase > mydatabase.sql')
subprocess.Popen(args)
I also tried with shell=True or or shell=False. In both cases, they still don't work.
I have read the docs, google for the answer for my problem, but I haven't got a clue how to show my problem. stackoverflow is probably my last hope.
Upvotes: 1
Views: 3757
Reputation: 69042
the problem here is the way you're redirecting the output.
">"
will always be interpreted as a literal >
, no matter if you use shell=True
or shell=False
shell=True
.the best way do do what you want would be to redirect the output to a file directly from python:
args = shlex.split('/opt/lampp/bin/mysqldump -uroot -ppassword --add-drop-database --database mydatabase')
output = open("mydatabase.sql", "w")
subprocess.Popen(args, stdout=output)
Upvotes: 2
Reputation: 309929
The problem may be the shell redirection. If you run with shell=True
don't use shlex.split
. In other words, try:
args = '/opt/lampp/bin/mysqldump -uroot -ppassword --add-drop-database --database mydatabase > mydatabase.sql'
subprocess.Popen(args,shell=True)
Of course, the safer solution would be to remove the shell redirection, use shlex.split on the arguments (without shell=True
), and use subprocess.PIPE
to capture the output (which you can then send to a file or do whatever you want with in your program)
For example:
args = '/opt/lampp/bin/mysqldump -uroot -ppassword --add-drop-database --database mydatabase'
p=psubprocess.Popen(shlex.split(args),shell=False,stdout=subprocess.PIPE)
p.wait()
returnvalue=p.returncode
data=p.stdout.read()
with open('mydatabase.sql','w') as f:
f.write(data)
...
If you don't want to do anything with the data in your program, you can do the redirection a little more easily as described by mata.
Upvotes: 1