如何在Python的Popen中将FIFO命名管道用作标准输入

4

我该如何让Popen使用FIFO命名管道作为标准输入?

import subprocess
import os
import time

FNAME = 'myfifo'
os.mkfifo(FNAME, mode=0o777)
f = os.open(FNAME, os.O_RDONLY)

process = subprocess.Popen(
    'wait2.sh',
    shell=True,
    stdout=subprocess.PIPE,
    stdin=f,
    stderr=subprocess.PIPE,
    universal_newlines=True,
)

while process.poll() is None:
    time.sleep(1)
    print("process.stdin", process.stdin)

如果我在终端窗口中运行这个脚本。
echo "Something" > myfifo

该进程以 process.stdin None 结束。看起来它没有从 FIFO 中获取标准输入。
1个回答

6
根据文档,只有在该字段的参数为PIPE时,Popen.stdin才不是None,而这在您的代码中并不是这种情况。
对我来说,这段代码运行得很好,正如预期的那样,它打印出了子进程中的“Line 1”和“Line 2”。
import subprocess
import os
import time

FNAME = 'myfifo'
os.mkfifo(FNAME, mode=0o777)

# Open read end of pipe. Open this in non-blocking mode since otherwise it
# may block until another process/threads opens the pipe for writing.
stdin = os.open(FNAME, os.O_RDONLY | os.O_NONBLOCK)

# Open the write end of pipe.
tochild = os.open(FNAME, os.O_WRONLY)
print('Pipe open (%d, %d)' % (stdin, tochild))

process = subprocess.Popen(
    ['/usr/bin/cat'],
    shell=True,
    stdout=None,
    stdin=stdin,
    stderr=None,
    universal_newlines=True,
)
print('child started: %s (%s)' % (str(process), str(process.stdin)))

# Close read end of pipe since it is not used in the parent process.
os.close(stdin)

# Write to child then close the write end to indicate to the child that
# the input is complete.
print('writing to child ...')
os.write(tochild, bytes('Line 1\n', 'utf-8'))
os.write(tochild, bytes('Line 2\n', 'utf-8'))
print('data written')
os.close(tochild)

# Wait for child to complete.
process.wait()
os.unlink(FNAME)

谢谢,这对我也有用。与此同时,我已经使用了screen实现了一些东西,但我会看一下这个。非常有趣。 - Ryan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接