python
  • subprocess
  • stdout
  • 2012-03-30 19 views 4 likes 
    4

    我正在尋找實現調用另一個腳本並捕獲其stdout的python腳本。所調用的腳本會包含一些輸入和輸出消息,例如獲取stdout以顯示包含輸入的調用腳本

    print ("Line 1 of Text") 
    variable = raw_input("Input 1 :") 
    print "Line 2 of Text Input: ", vairable 
    

    我運行代碼的部分是

    import subprocess 
    
    cmd='testfile.py' 
    p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE) 
    so, se = p.communicate() 
    print(so) 
    

    所發生的問題是,標準輸出不打印,直到後腳本已執行。這會留下空白的提示,等待用戶輸入。有沒有辦法讓被調用的腳本仍在運行時輸出stdout?

    感謝,

    +0

    從這裏:HTTP://計算器。COM /問題/ 230751 /如何對平齊輸出的 - 蟒蛇打印 進口SYS sys.stdout.flush() – 2012-03-30 03:48:23

    +0

    哪個操作系統,你定位?這種類型的應用程序在Windows上有一些奇怪的現象 – Fuzz 2012-03-31 03:37:41

    +0

    @Fuzz腳本需要在Windows XP和7上運行 – Scavenger 2012-03-31 03:49:23

    回答

    3

    這裏有兩個問題。

    1. 首先,python緩衝輸出到標準輸出,你需要防止這種情況。您可以按照Ilia Frenkel的建議在testfile.py中插入sys.stdout.flush()的呼叫,或者您可以使用python -u執行testfile.py以及未緩衝的I/O。 (請參閱Ilia鏈接到的other stack overflow question。)

    2. 您需要一種方法來異步讀取子進程中的數據,然後在準備好輸入時打印您讀取的數據,以便提示用戶出現。爲此,有一個asynchronous version of the subprocess module將是非常有幫助的。

    我下載的異步子進程,並重新寫你的腳本中使用它,用python -u獲得無緩衝I/O一起:當我運行使用python -u我拿到這個劇本

    import async_subprocess as subprocess 
    
    cmd = ['python', '-u', 'testfile.py'] 
    p = subprocess.Popen(cmd, stdout=subprocess.PIPE) 
    so = p.asyncread() 
    print so, 
    (so, se) = p.communicate() 
    print so 
    

    以下結果:

    $ python -u script.py 
    Line 1 of Text 
    Input 1: 
    

    和腳本暫停,等待輸入。這是理想的結果。

    如果我再鍵入的東西(例如 「你好」)我得到以下幾點:

    $ python -u script.py 
    Line 1 of Text 
    Input 1:Hullo 
    Line 2 of Text Input: Hullo 
    
    +0

    謝謝!它工作正常,但是如果測試文件的內容發生變化並且有第二個輸入,那麼它將因通信()運行直到達到文件結尾而停止工作 – Scavenger 2012-04-02 04:02:50

    1

    你不需要捕捉到它的stdout真的,只是將孩子程序打印出它的東西和退出,而不是輸出送入你的父程序,並打印它。如果你需要變量輸出,只需使用一個函數。

    但無論如何,這不是你問的。

    我實際上是從另一個計算器的問題得到了這個:

    import subprocess, sys 
    cmd='testfile.py' 
    p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE) 
    while True: 
        out = p.stdout.read(20) 
        if out == '' and p.poll() != None: 
         break 
        if out != '': 
         sys.stdout.write(out) 
         sys.stdout.flush() 
    

    首先,它打開了你的進程:那麼它不斷p讀取輸出並打印到使用sys.stdout.write屏幕。使這一切工作的部分是sys.stdout.flush(),它將不斷「清除」程序的輸出。

    +0

    @ bear605我運行代碼,但它不起作用。第一個打印命令沒有出現,並且腳本被按鍵沒有做任何事情。這可能是因爲我在Windows上運行。 – Scavenger 2012-04-01 22:54:32

    相關問題