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