1

为了与一个启动一次并在单独进程中运行的 shell 通信,我使用了Popen from subprocess.

import os
from subprocess import Popen, PIPE

def server():
    FIFO_PATH = '/tmp/my_fifo'
    FIFO_PATH2 = '/tmp/in_fifo'
    if os.path.exists(FIFO_PATH):
        os.unlink(FIFO_PATH)
    if os.path.exists(FIFO_PATH2):
        os.unlink(FIFO_PATH2)

    if not os.path.exists(FIFO_PATH2):
        os.mkfifo(FIFO_PATH2)
        in_fifo = open(FIFO_PATH2, 'rw+')
        print "in_fifo:", in_fifo

    if not os.path.exists(FIFO_PATH):
        os.mkfifo(FIFO_PATH)
        my_fifo = open(FIFO_PATH, 'rw+')
        print "my_fifo:", my_fifo

    p = Popen(['python', '-u', 'shell.py'], shell=False, stdin=in_fifo, stdout=my_fifo)

def read():
    FIFO_PATH = '/tmp/my_fifo'
    i=0
    while i < 10:
        ++i
        print i, open(FIFO_PATH, 'r').readline()

def write(input):
    FIFO_PATH2 = '/tmp/in_fifo'

    pipe = open(FIFO_PATH2, 'w+')
    pipe.write(input+'\n')

def test():
    server()
    write('test')
    read()

shell.py

Input = ' '
print 'shell called'
while Input!= 'z':
    Input=raw_input()
    print 'input ', Input

    if Input != '':
        if Input == 'test':
            print 'Yeehhaaaaa it works'

所以调用test()给出以下结果

in_fifo: <open file '/tmp/in_fifo', mode 'rw+' at 0x7f0a4e17ed20>
my_fifo: <open file '/tmp/my_fifo', mode 'rw+' at 0x7f0a4e17edb0>
0 shell called

0 input  test

问题

为什么只打印第一行?如何打印所有行?

此外,我不确定 FIFO 的正确使用。也许有更好的方法来完成这项工作。我愿意接受任何建议。

使用p调用对我p.stdin.write()来说p.stdout.readline()不是解决方案,因为我必须在没有实例的情况下从 javascript 调用函数p

4

1 回答 1

1

从手册页mkfifo

打开一个 FIFO 进行读取通常会阻塞,直到某个其他进程打开同一个 FIFO 进行写入,反之亦然。有关 FIFO 特殊文件的非阻塞处理,请参见 fifo(7)。

因此,第二次打开 FIFO 进行读取时,调用会阻塞。这可以在按下 Ctrl+C 后的回溯中看到:

^CTraceback (most recent call last):
0
Traceback (most recent call last):
  File "shell_fifo.py", line 51, in <module>
  File "shell.py", line 4, in <module>
    test()
  File "shell_fifo.py", line 48, in test
        read()
  File "shell_fifo.py", line 29, in read
    print i, open(FIFO_PATH, 'r').readline() # read() is blocked here
KeyboardInterrupt
Input=raw_input()
KeyboardInterrupt

更改您的read函数,使其仅打开 FIFO 一次:

def read():
    FIFO_PATH = '/tmp/my_fifo'
    i = 0
    with open(FIFO_PATH, 'r') as read_fifo:
        while i < 10:
            i += 1
            print i, read_fifo.readline().rstrip()

你应该看到这样的输出:

in_fifo: <open file '/tmp/in_fifo', mode 'rw+' at 0x7f1ba655b5d0>
my_fifo: <open file '/tmp/my_fifo', mode 'rw+' at 0x7f1ba655b540>
1 shell called
2 input  test
3 Yeehhaaaaa it works
于 2016-06-09T20:36:31.830 回答