bash / python停止从fifo读取

时间:2017-10-09 13:17:07

标签: bash fifo

我试图让一个简短的python脚本从bash / linux下的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的行为

---另一个编辑---

如果我在输入" STOP"之后搜索python进程。我再也找不到了。这意味着python进程正在完成。问题似乎是tail -f和bash之间的一些交互。

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

好吧,我想我已经知道发生了什么,它与python无关。

当您向命名管道回显某些内容时,会在末尾添加EOFtail -fEOF转换为EOL。这意味着如果我不使用tail -f,而是使用cat将命名管道的内容传递给python脚本的stdin,python将失去与stdin的连接在第一行末尾阅读EOF之后{1}}。从那时起,尝试从stdin阅读将会产生EOF。因此,python脚本将显示read\n的无限列表。如果在使用tail -f时退出python脚本,tail -f在我向命名管道添加其他内容之前不知道这一点。

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

它是尾巴。

./tst.py<myfifo &

然后将您想要的任何内容发送到管道中。代码正在运行(虽然我不得不在我的python版本中删除sys的引号。)你的问题是tail仍然在-f follow模式下运行。