2

Oracle exp/imp コマンドを使用し、sqlplus を介して SQL スクリプトを開始するための GUI を作成しています。サブプロセス クラスを使用すると、コマンドを簡単に起動できますが、追加の機能が必要です。wxPython GUI を使用するときにコマンド プロンプトを削除したいのですが、exp/imp コマンドの出力を表示する方法が必要です。

私はすでにこれらの2つの方法を試しました:

command = "exp userid=user/pwd@nsn file=dump.dmp"

process = subprocess.Popen(command, stdout=subprocess.PIPE)
output = process.communicate()[0]

process = subprocess.Popen(command, stdout=subprocess.PIPE)
process.wait()
output = process.stdout.read()

これらの方法の 1 つ (どの方法を忘れたか) を使用して、exp/imp の出力を実際に取得しましたが、コマンドが終了した後でのみ、これらの実行時間が長くなる可能性のある操作中に頻繁に更新する必要があるため、これはまったく価値がありません。また、sqlplus は、エラーが発生したときに何らかの入力を必要とするため、さらに多くの問題を引き起こしました。これが発生すると、python はプロセスが終了するのを待ちますが、ユーザーにはプロンプトが表示されないため、待機時間や何をすべきかわかりません...

私が欲しいのは、標準のコマンドラインで表示できるすべてのものを出力するラッパーです。これをファイルに記録し、wxPython コントロール内に表示したいと考えています。

このページのコードも試しました: http://code.activestate.com/recipes/440554/ しかし、これも出力を読み取ることができません。この回答の OutputWrapper も機能しません: wxPython アプリケーションからすべての例外をキャプチャするにはどうすればよいですか?

どんな助けでも大歓迎です!

編集:
サブプロセスは出力をフラッシュしていないようです。私はすでに .readline() で試しました。
私のツールは Windows と UNIX で実行する必要があるため、Windows バージョンがない場合、pexpect は解決策になりません。また、exp、imp、および sqlplus の機能全体を再構築する必要があるため、cx_oracle を使用するのは非常にやり過ぎです。

4

4 に答える 4

1

解決策は、コマンドにリストを使用することです

command = ["exp", "userid=user/pwd@nsn", "file=dump.dmp"]
process = subprocess.Popen(command, stdout=subprocess.PIPE)

次に、process.stdout を 1 行ずつ読み取ります。

line = process.stdout.readline()

そうすれば、待つことなく GUI を更新できます。実行中のサブプロセス (exp) が出力をフラッシュする場合出力がバッファリングされている可能性があり、出力バッファがいっぱいになるまで何も表示されません。その場合は、おそらく運が悪いです。

于 2009-02-10T10:59:05.980 に答える
1

Linux を使用している場合は、pexpectを確認してください。それはまさにあなたが望むことをします。

Windows で作業する必要がある場合は、を介して CL を実行する代わりに、弾丸をかじってcx_Oraclesubprocessなどの Oracle への Python バインディングを使用する必要があります。

于 2009-02-10T11:51:25.510 に答える
0

これらのソリューションは stderr もキャプチャできますか? 上記の stdout= オプションがあることがわかります。stderr も確実に取得するにはどうすればよいですか? もう 1 つの質問は、import logging/import logging.handlers を使用してコマンド stdout/stderr をキャプチャする方法があるかどうかです。ロガーをフォーマッター/ローテーターなどのビルドで使用できると興味深いでしょう。

于 2009-02-20T13:49:28.597 に答える
-1

これを試して:

import subprocess

command = "ping google.com"

process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
output = process.stdout
while 1:
    print output.readline(),
于 2009-02-10T10:55:30.683 に答える