簡體   English   中英

將stdout重定向到管道時,python子進程輸出消失

[英]python subprocess output disappear when redirect stdout to pipe

我目前正在處理一段代碼,該代碼使用一個腳本來獲取實時數據並將其打印到我的屏幕上。

當我在python控制台中運行腳本(我無法訪問視圖)時,使用:

>>>> myproc = subprocess.Popen('command')
...print....

當數據到來時,輸出完美地打印在我的屏幕上。

但是,如果我將其更改為

>>>> myproc = subprocess.Popen('command', stdout = subprocess.PIPE, stderr = subprocess.PIPE)`
>>>> while True:
>>>>    print(myproc.stdout.readline())
... perfectly no print....

有零輸出(我也檢查過stderr,什么都沒有)

我想這里的問題是我將stdout設置為subprocess.PIPE ,我應該改變它。

但是,因為我需要存儲來自myproc的數據,並且使用stdout是迄今為止我所知道的唯一允許我這樣做的方法,所以我對如何更改代碼的想法已經不多了。

請告訴我我能在這做什么,還請告訴我為什么會這樣。

謝謝

編輯:我的腳本偵聽實時數據,因此它將繼續運行,直到我手動中斷它。 我想在它實際終止之前打印。

第二次編輯

我發現丟失的輸出去了...我必須改變它

myproc = subprocess.Popen('command', stdout=sys.stdout)然后使用

While True:
    if myproc.stdout is not None:
          print(myproc.stdout)

輸出顯示。 但這只是超級丑陋而且輸出可能非常難以預測..任何人都可以提供更好的方法來處理這個丑陋的事情嗎?

您應該使用通信來等待進程完成並獲取stdout和stderr處理程序:

myproc = subprocess.Popen(['command'], stdout = subprocess.PIPE, stderr = subprocess.PIPE)
out, err = myproc.communicate()
print("STDOUT:")
for line in myproc.stdout:
    print(line)
print("STDERR:")
for line in myproc.stderr:
    print(line)

另一種可能性是它打印到stderr而不是stdout。

最后,如果你Popen命令的單個字符串參數調用Popen ,你還應該設置shell=True來生成一個shell,否則你應該使用一個列表。 雖然如果你沒有任何參數,它可以在不使用列表的情況下工作。


那么您可能會對以下代碼段感興趣:

    p = subprocess.Popen([command], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    out = io.TextIOWrapper(p.stdout)
    err = io.TextIOWrapper(p.stderr)
    while p.poll() == None:
        ret = select.select([out.fileno(), err.fileno()], [], [])
        for fd in ret[0]:
            if fd == out.fileno():
                output_parser(out.readline())
            if fd == err.fileno():
                output_parser(err.readline())
    for line in out.read().split('\n'):
        output_parser(line)
    for line in err.read().split('\n'):
        output_parser(line)

取自我最近寫的代碼:

https://github.com/guyzmo/pyvod/blob/master/vod/video.py#L70

HTH

如果這是linux或osx,問題是您需要使用偽終端使程序認為它應該以交互方式運行。 python pexpect模塊用於處理這個問題。 它創建了一個pty並將其用於stdout。 您可以直接使用pexpect或閱讀其來源,了解烹飪自己的東西。 此示例將命令輸出發送到屏幕和磁盤上的文件。

import pexpect
proc = pexpect.spawn('command', logfile=open('mylog.txt','w'),
    searchwindowsize=80, timeout=-1)
for line in proc:
    print(line.strip())

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM