Reputation: 1186
I'm trying to get a short python script to read from a fifo under bash/linux and then stop when a certain word is received. i've done the following
in 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")
And i'm running the script like this:
mkfifo myfifo
tail -f myfifo | python main.py
In another shell window I enter:
echo "foobar" > myfifo # "myfifo read" echoed in the other window
echo "STOP" > myfifo # "finished" echoed in other window
However, the process in the other window doesn't stop but remains open until i echo something else to myfifo.
Does anybody know what's going on here and how to get the python process to quit?
--- edit ---
I've just rewritten main.py as a bash script and it has the same problem. This seems to be a behaviour of tail -f which i am unfamiliar with
--- another edit ---
If i search for the python process after having entered "STOP" i can't find it anymore. This means that the python process is finishing. The problem seems to be some interaction between tail -f and bash.
--- possibly final edit ---
Okay, i think i've worked out what's going on and it has nothing to do with python.
when you echo something to a named pipe, an EOF
is added to the end. tail -f
transmutes an EOF
into an EOL
. That means that if i don't use tail -f
but instead use cat
to pipe the contents of the named pipe to stdin
of the python script, python will lose a connection to stdin
after having read the EOF
at the end of the first line. From then on, trying to read from stdin
will result in an EOF
. For this reason, the python script will display an infinite list of read\n
. If, when using tail -f
the python script quits, tail -f
doesn't know about this until i add something else to the named pipe.
Upvotes: 1
Views: 450
Reputation: 15246
It's the tail.
./tst.py<myfifo &
then send anything you want into the pipe. The code is working (though I had to strip the quotes off sys for my version of python.) Your problem is that tail is still running in -f follow mode.
Upvotes: 0
Reputation: 74596
tail -f
keeps the pipe open indefinitely, so you should call sys.stdin.close()
once you're done reading from it:
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")
Off-topic, but I also changed your import "sys"
to import sys
.
Upvotes: 1