簡體   English   中英

python子進程多個stdin.write和stdout.read

[英]python subprocess multiple stdin.write and stdout.read

感謝您抽出寶貴時間回答問題。 我正在使用Python 3.4,並且有兩個簡單的python程序。 一種是名為test.py的程序,該程序需要用戶輸入並打印某些內容。

while True:
    print("enter something...")
    x = input()
    print(x)
    time.sleep(1)

要將輸入發送到該程序,我還有另一個使用子進程的程序:

from subprocess import Popen, PIPE

cat = Popen('python test.py', shell=True, stdin=PIPE, stdout=PIPE)
cat.stdin.write("hello, world!\n")
cat.stdin.flush()
print(cat.stdout.readline())

cat.stdin.write("and another line\n")
cat.stdin.flush()
print(cat.stdout.readline())

但是,當我運行上述程序時,出現錯誤:

enter something...

hello, world!
Traceback (most recent call last):
  File "/opt/test.py", line 9, in <module>
    x = input()
EOFError: EOF when reading a line
Exception ignored in: <_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'>
BrokenPipeError: [Errno 32] Broken pipe

而且,如果我用“ cat”之類的標准linux命令替換了test.py,一切都會按預期進行。

有什么辦法可以發送多個stdin寫入並讀回多個stdout?

通常,應將pexpect用於交互式程序(基於對話框的交互)

您的特定問題可能是由python版本不匹配引起的(您認為您的代碼是使用Python 3執行的,而實際上可能是使用Python 2執行的)。 第二個問題( EOFError )是預期的:要么在子腳本中捕獲它,要么提供一個讓孩子退出的信號(在下面的代碼示例中,我使用空行)。

這是一個Python 3代碼,在Python 2上大聲失敗:

#!/usr/bin/env python3
import sys
from subprocess import Popen, PIPE

with Popen([sys.executable, '-u', 'test.py'], stdin=PIPE, stdout=PIPE,
           universal_newlines=True, bufsize=1) as cat:
    for input_string in ["hello, world!", "and another line", ""]:
        print(input_string, file=cat.stdin, flush=True)
        print(cat.stdout.readline(), end='')

注意:

這是相應的test.py

#!/usr/bin/env python3
import time

while True:
    x = input("enter something...")
    if not x: # exit if the input is empty
        break
    print(x)
    time.sleep(1)

產量

enter something...hello, world!
enter something...and another line
enter something...

注意: "enter something..."后沒有新行

它可以工作,但很脆弱,請閱讀問:為什么不只使用管道(popen())? 改用pexpect


如果輸入是有限的並且不依賴於輸出,則可以一次全部傳遞:

#!/usr/bin/env python3
import sys
from subprocess import check_output

output = check_output([sys.executable, 'test.py'],
                      input="\n".join(["hello, world!", "and another line"]),
                      universal_newlines=True)
print(output, end='')

此版本要求孩子正確處理EOF:

#!/usr/bin/env python3
import time

while True:
    try:
        x = input("enter something...")
    except EOFError:
        break # no more input

    print(x)
    time.sleep(1)

輸出是相同的(如上所示)。

暫無
暫無

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

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