2011-03-21 57 views
18

我正在尋求從外部進程向現有進程的STDIN寫入數據的方法,並在stackoverlow中發現了類似的問題How do you stream data into the STDIN of a program from different local/remote processes in Python?如何從外部進程將數據寫入現有進程的STDIN?

在該線程中,@Michael說我們可以像下面那樣獲取現有進程的文件描述符,並允許在Linux上將數據寫入它們。

/proc/$PID/fd/ 

所以,我創建了下面列出的數據寫入測試從外部過程腳本的STDIN(和TTY)一個簡單的腳本。

#!/usr/bin/env python 

import os, sys 

def get_ttyname(): 
    for f in sys.stdin, sys.stdout, sys.stderr: 
     if f.isatty(): 
      return os.ttyname(f.fileno()) 
    return None 

if __name__ == "__main__": 
    print("Try commands below") 

    print("$ echo 'foobar' > {0}".format(get_ttyname())) 
    print("$ echo 'foobar' > /proc/{0}/fd/0".format(os.getpid())) 

    print("read :: [" + sys.stdin.readline() + "]") 

這個測試腳本顯示的STDINTTY路徑,然後等待一個寫它的STDIN

我啓動了這個腳本,在下面得到了消息。

Try commands below 
$ echo 'foobar' > /dev/pts/6 
$ echo 'foobar' > /proc/3308/fd/0 

所以,我執行來自其它終端的命令echo 'foobar' > /dev/pts/6echo 'foobar' > /proc/3308/fd/0。執行完這兩個命令之後,消息foobar在運行測試腳本的終端上顯示兩次,但僅此而已。行print("read :: [" + sys.stdin.readline() + "]")未執行。

是否有任何方法將數據從外部進程寫入現有進程的STDIN(或其他文件描述符),即調用其他進程執行print("read :: [" + sys.stdin.readline() + "]")行?

+1

命名管道(請參見man mkfifo')做你想要的嗎? – Andy 2011-03-21 16:05:11

+0

感謝您的建議。我會看看named-pipe。 – mooz 2011-03-21 18:20:47

回答

16

您的代碼將無法使用。
/proc/pid/fd/0是到/dev/pts/6文件的鏈接。

$回聲 'foobar的'>的/ dev/PTS/6
$回聲 'foobar的'>/proc /進程/ FD/0

由於兩個命令寫入到終端。該輸入進入終端,而不是進程。

這將工作,如果標準輸入爲inlined是管道。
例如,test.py是:

#!/usr/bin/python 

import os, sys 
if __name__ == "__main__": 
    print("Try commands below") 
    print("$ echo 'foobar' > /proc/{0}/fd/0".format(os.getpid())) 
    while True: 
     print("read :: [" + sys.stdin.readline() + "]") 
     pass 

運行此爲:

$ (while [ 1 ]; do sleep 1; done) | python test.py 
從另一端寫的東西 /proc/pid/fd/0

現在,它會來到test.py

+0

您提出的腳本和命令可以正常工作。所以,一旦我像'$ python test.py'那樣從沒有管道的終端創建進程,就沒有辦法執行'print(「read :: [」+ sys.stdin.readline()+「]」)'from外部過程? – mooz 2011-03-21 18:13:40

+1

@mooz:AFAIK沒有辦法做到這一點。 – 2011-03-24 06:39:54

3

我想在這裏的離開我發現有用的例子。這是對我的機器上間歇性失敗的上述真實技巧的輕微修改。

# pipe cat to your long running process 
(cat) | ./your_server & 
server_pid=$! 
# send an echo to your cat process that will close cat and in my hypothetical case the server too 
echo "quit\n" > "/proc/$server_pid/fd/0" 

這是對我很有幫助,因爲我不能用mkfifo,這是完美的這種情況下特殊原因。

相關問題