1

我想调用一个子进程来备份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 可能是我最后的希望。

4

2 回答 2

2

这里的问题是您重定向输出的方式。

  • ">"如果您将命令作为参数列表传递,则>无论您使用shell=Trueshell=False
  • 如果您将命令作为单个字符串传递,那么它应该可以工作,但前提是您有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)
    
于 2012-05-01T12:59:06.667 回答
1

问题可能是外壳重定向。如果你运行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)

...

如果您不想对程序中的数据做任何事情,您可以更轻松地进行重定向,如 mata 所述

于 2012-05-01T12:53:58.357 回答