2016-11-14 8 views
1

私は彼が私に送った答えに応じて多くのコマンドをcmdに送信しようとしています。多くのコマンドをcmdに送信

import subprocess 
process = subprocess.Popen("cmd.exe", stdout=subprocess.PIPE,stdin=subprocess.PIPE) 
answer = process.communicate(input="some command\n" + '\n')[0] 

""" 
choosing another command according to answer 
""" 

print process.communicate(input=another_command + '\n')[0] 
process.kill() 

問題を解決する方法上の任意のアイデア:

ValueError: I/O operation on closed file 

が、私はこのような何かを実行している:

私は、実行時エラーメッセージを取得していますか?

ありがとうございました!

+0

より大きな画像を表示できますか?あなたは 'process.kill()'の後にあなたのコマンドを送りますか?そうでない場合、コードのいくつかの例を提供できますか( ''いくつかのコマンド ''の代わりに実際のコマンドを使用します)? cmdで実行しようとするコマンドがシェルを終了させる可能性があります。 – woockashek

+0

'process.kill()'と両方のコマンドが '' ipconfig \ n "'でなくても。最初のコマンドは動作していて、2番目のコマンドはランタイムエラー –

+0

を実行します。コマンドを実行すると、おそらく戻りコードが返され、Popenオブジェクトが閉じられます。たとえば、ipconfigを実行して 'process.poll()'を実行すると、おそらく '0'の戻りコードが表示されます。 – sytech

答えて

1

cmd.exeにコマンドを送信しないでください。

subprocess.Popen("dir", shell=True, stdout=subprocess.PIPE,stdin=subprocess.PIPE) 

おそらく、このように使用する場合、標準入力にはパイプは必要ありません。

+0

もし 'sub-processing'と' communicate() 'を使ってそれをやりたいのであれば、可能でしょうか?ご助力ありがとうございます! –

+0

@EyalSサブプロセスと通信()を使用する、または特別な問題を解決するタスクはありますか? 対話コマンドを対話コマンドに入力することができます。しかし、私はあなたがcmdにパイプコマンドを使用することはできないと思います。 – jhinghaus

+0

何らかの理由で私のコンピュータがcmd.exeをシステムプログラムとして認識しないため、すべてのパスが完全に正しいので、サブプロセスを使用して問題を回避しようとしました。 –

0

エラーは正常です。 communicateは、サブプロセスがその出力をフラッシュできるように、それ以上入力が保留されていないことを示すサブプロセスの標準入力を閉じます。したがって、複数のcommunicateコールを1つのサブプロセスで連鎖させることはできません。

しかし、コマンドが単純で(入力データの多くはkバイトではない)、次のコマンドを送信する前に1つのコマンドの出力を収集して処理する必要がない場合は、すべてのコマンドを書き込むことができますそれらの2つの間でできるだけ多くの出力を読み込みます。最後にコマンドを実行すると、サブプロセスの標準入力を閉じて終了するまで待つことができますが、出力を照合することもできます。

process = subprocess.Popen("cmd.exe", stdout=subprocess.PIPE, stdin=subprocess.PIPE) 
process.stdin.write("some command\n\n") 
partial_answer = process.stdout.read() # all or part of the answer can still be buffered subprocess side 
... 
process.stdin.write("some other command\n\n") 
... 
# after last command, time to close subprocess 
process.stdin.close() 
retcode = None 
while True: 
    end_of_answer += process.stdout.read() 
    if retcode is not None: break 
+0

専用のリーダースレッドを使用していない場合は、デッドロックに注意してください。 Windowsでは、['PeekNamedPipe'](https://msdn.microsoft。msvcrt.get_osfhandle(process.stdout.fileno())からのハンドルを使用して、使用可能なバイト数を取得します。com/en-us/library/aa365779そうすれば、利用可能なデータをさらに読み込もうとしてデッドロックすることはなく、cmd.exeはstdinでコマンドを待ってブロックされます。シェルを操作する場合は、カスタムプロンプトを設定し、プロンプトが読み取られるまで一度にバイトを読み取ることもできます。 – eryksun

+0

また、 'flush'を何度も呼び出さずに済むようにするには、' bufsize = 0'を渡して 'process.stdin'をバッファしないようにしてください。そして、cmd.exeは' "\ r" 、ではありません。\ n \ n ""。 – eryksun

関連する問題