2012-05-01 13 views
1

mysqlデータベースをバックアップするサブプロセスを呼び出したいと思います。 の端末で正常に走った(とmydatabase.sqlという名前のファイルを作成した)コマンドラインは次のとおりです。Python - subprocess.check_callはCalledProcessError例外を返します

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) 

exeptionは(何のファイルが作成されていない)発生します

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) 

私はまた、偽= Trueかまたはシェル=シェルで試してみました。どちらの場合も、まだ動作しません。

私は自分の問題の答えをgoogleで見つけましたが、問題を示す手がかりがありません。おそらく私の最後の希望です。

答えて

2

ここでの問題は、出力をリダイレクトする方法です。

  • あなたは引数のリストのようにコマンドを渡した場合、その後、">"は常にリテラル>として解釈されます、どんなにあなたが1つの文字列としてコマンドを渡す場合はshell=Trueまたはshell=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) 
    
+0

ありがとうございました!私はあなたの答えをプラスしたいですが、私はより多くの担当者が必要です。 –

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=Trueなし)の引数にshlex.splitを使用し、出力をキャプチャする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

+0

はどうもありがとうございました!私はあなたの答えをプラスしたいですが、私はより多くの担当者が必要です。 –

関連する問題