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)

もちろん、より安全な解決策は、シェルリダイレクトを削除し、引数に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 に答える