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.exe 来运行您的程序,因为您的程序已经在 cmd shell 中运行。

我建议你使用 subprocess 直接调用程序,并在你的代码中处理异常/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 回答