我想调用子进程来备份mysql数据库。 在终端中运行良好的命令行(并创建了一个名为mydatabase.sql的文件)是:
mysqldump -uroot -ppassword --add-drop-database --database mydatabase > mydatabase.sql
现在由python运行以调用子进程的代码:
args = shlex.split('mysqldump -uroot -ppassword --add-drop-database --database mydatabase > mydatabase.sql')
subprocess.check_call(args)
引发了异常(没有创建文件):
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
我尝试了不同的方法,但它们仍然不起作用:
args = shlex.split('/opt/lampp/bin/mysqldump -uroot -ppassword --add-drop-database --database mydatabase > mydatabase.sql')
subprocess.check_call(args)
或
args = shlex.split('/opt/lampp/bin/mysqldump -uroot -ppassword --add-drop-database --database mydatabase > mydatabase.sql')
subprocess.Popen(args)
我也试过shell = True或者shell = False。在这两种情况下,它们仍然不起作用。
我已经阅读了文档,谷歌搜索我的问题的答案,但我还没有弄清楚如何显示我的问题。 stackoverflow可能是我最后的希望。
答案 0 :(得分:2)
这里的问题是你重定向输出的方式。
">"
将始终被解释为文字>
,无论您使用shell=True
还是shell=False
< / LI>
shell=True
。做你想做的最好的方法就是直接从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)
答案 1 :(得分:1)
问题可能是shell重定向。如果您使用shell=True
投放,请不要使用shlex.split
。换句话说,尝试:
args = '/opt/lampp/bin/mysqldump -uroot -ppassword --add-drop-database --database mydatabase > mydatabase.sql'
subprocess.Popen(args,shell=True)
当然,更安全的解决方案是删除shell重定向,在参数上使用shlex.split(不使用shell=True
),并使用subprocess.PIPE
捕获输出(然后可以发送)到一个文件或在你的程序中做任何你想做的事情)
例如:
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)
...
如果您不想对程序中的数据执行任何操作,则可以更轻松地进行重定向as described by mata。