2014-04-01 33 views
2

我正在運行使用popen3的進程,並嘗試讀取stdout流。我希望能夠在每個字符放入標準輸出時檢測每個字符,但即使使用stdout.getc,只有換行符時我才能得到任何輸出。如何在Ruby中使用Open#popen3讀取未緩衝的stdout

任何提示?我已經看到這回答與stdin.getc,但不是標準輸出。

回答

2

您遇到的問題是,大多數程序在通過管道運行時(這是popen發生的情況)將使用緩衝輸出運行。

但是你要找的是無緩衝輸出。無緩衝輸出僅在進程連接到PTY時發生。即如地獄。

將進程附加到管道時,輸出將被緩衝,除非進程在其輸出處理期間明確調用flush

您有幾種選擇:

  1. 如果您對要與popen運行,那麼強制stdout中的flush調用每個輸出序列之後的源代碼控制。

  2. 您可以嘗試運行stdbuf -o0下的命令,該命令嘗試強制執行無緩衝的輸出。
    看到這個問題:
    Force line-buffering of stdout when piping to tee
    但是,這並不能保證適用於所有程序。

  3. 您可以嘗試使用Ruby PTY庫而不是popen來使程序在僞終端下運行,因此可以無緩衝地運行。看到這個答案:
    Continuously read from STDOUT of external process in Ruby

選項3是最有可能要運行和監控任何程序工作,而其他選項可能會不依賴於程序正​​在運行,如果你的工作有權訪問該程序的源代碼。

+0

_無緩衝輸出僅在進程連接到PTY時發生。即一個shell._如果標準輸出連接到「交互設備」(即終端,不僅是PTY),則glibc的默認設置是使stderr無緩衝,但在標準輸出(不是無緩衝!)上執行*行緩衝*。請參閱http://stackoverflow.com/a/3746795/601203。殼不是PTY。 – hagello

相關問題