3

次の例があります。

import subprocess

p = subprocess.Popen("cmd",stdin = subprocess.PIPE, stdout=subprocess.PIPE )
p.stdin.write(b'cd\\' + b'\r\n')
p.stdin.write(b'dir' + b'\r\n')
p.stdin.write(b'\r\n')



while True:
    line = p.stdout.readline()
    print(line.decode('ascii'), end='')
    if line.rstrip().decode('ascii') == 'C:\>': #I need to check at this point if there is new data in the PIPE
        print('End of File')
        break

サブプロセスからの出力を PIPE でリッスンしていますが、PIPE から新しいデータが来ない場合は、読み取りを停止したいと思います。PIPE が空であることを示す制御ステートメントが必要です。これは、プロセスがフリーズしたり、予期しない結果で終了した場合の問題を回避するのに役立ちます。

4

1 に答える 1

2

プロセスが終了するか、読み取りを停止する予定のシグナルがない限り、パイプにデータがあるかどうかを事前に知る良い方法はありません。コマンドは、指定したバイト数に達したときにのみ終了するためです。 [.read(n)] を読みたい、改行文字 [.readline()] に到達する、またはファイルの最後に到達する (プロセスが終了するまで存在しない)。

ただし、プログラムは既に cmd シェルで実行されているため、プログラムを実行するために cmd.exe を実行する必要はありません。

サブプロセスを使用してプログラムを直接呼び出し、コードで例外/ return_code を処理することをお勧めします。あなたは次のようなことができます...

import subprocess
import time

p = subprocess.Popen("your_program.exe",
                     "-f", "filename",
                     stdin=subprocess.PIPE,
                     stdout=subprocess.PIPE)

# If you have to use stdin, do it here.
p.stdin.write('lawl here are my inputs\n')

run_for = 0
while p.poll() == None:
    time.sleep(1)
    if run_for > 10:
        p.kill()
        break
    run_for += 1

if p.return_code == 0:
    ...handle success...
else:
    ...handle failure...

これをループで実行し、次のファイルを実行する新しいプロセスを起動できます。

プログラムをスピンアップするのにそれほどコストがかかる場合(そうでない場合は、恥ずかしいので今すぐ読むのをやめてください)、おそらく(そしてこれは完全なハックですが)プロセスがしばらく実行された後、特に渡すことができますのように、p.stdin への奇妙だが無害な文字列p.stdin.write("\n~%$%~\n")

それを回避できれば、次のようなことができます...

for line in p.stdout.readlines():
    if '~%$%~' in line:
        break

しかし、なんてこった、そうしないでください。それはそのようなハックです。

于 2012-04-20T00:07:25.640 に答える