2017-10-09 230 views
1

我试图从bash/linux下的fifo中读取一个简短的python脚本,然后在收到某个单词时停止。我已经做了以下bash/python从fifo停止读取

在main.py

import "sys" 
while True: 
    line = sys.stdin.readline().rstrip() 
    sys.stdout.write(line + " read\n") 
    if line=="STOP": 
     break 
sys.stdout.write("finished\n") 

而且我运行这样的脚本:

mkfifo myfifo 
tail -f myfifo | python main.py 

在另一个shell窗口我输入:

echo "foobar" > myfifo # "myfifo read" echoed in the other window 
echo "STOP" > myfifo # "finished" echoed in other window 

但是,其他窗口中的进程并不会停止,而是一直保持打开状态,直到我向myfifo回复其他内容。

有没有人知道这里发生了什么,以及如何让python进程退出?

---编辑---

我刚刚改写main.py作为一个bash脚本,它有同样的问题。这似乎是尾-f对此我不熟悉

---另一个编辑的行为---

如果我搜索Python进程已进入后“STOP”我无法找到它了。这意味着Python进程正在完成。这个问题似乎是tail -f和bash之间的一些相互作用。

---可能最终编辑---

好吧,我想我已经制定了这是怎么回事,并没有任何与蟒蛇。

当您对某个命名管道回显某些内容时,会在末尾添加一个EOFtail -fEOF转换为EOL。这意味着如果我不使用tail -f,而是使用cat将命名管道的内容管道化为python脚本的stdin,则python将在第一行的末尾读取EOF后失去与stdin的连接。从此,试图从stdin读取将导致EOF。出于这个原因,python脚本将显示无限列表read\n。如果在使用tail -f时python脚本退出,tail -f不知道这些,直到我将其他内容添加到命名管道。

回答

1

tail -f保持打开管无限期,所以你应该叫sys.stdin.close()一旦您完成了从中读取:

import sys 

while True: 
    line = sys.stdin.readline().rstrip() 
    sys.stdout.write(line + " read\n") 
    if line == "STOP": 
     break 

sys.stdin.close() 
sys.stdout.write("finished\n") 

题外话,但我也改变了你的import "sys"import sys

0

这是尾巴。

./tst.py<myfifo & 

然后发送任何你想要的管道。该代码正在工作(虽然我不得不脱离我的python版本sys的报价)。你的问题是,尾巴仍然在-f follow模式下运行。

+0

这样做的麻烦是,如果我然后回声一些myfifo,python脚本将输出一个无限列表“读\ n”。我不知道为什么。 – ehrt1974

+0

编辑您的原始文章,以准确显示您如何设置和执行。除了FIFO之外,不要使用尾部或管道。保持尽可能简单和最小化。 –