The way I understand fifos, the open of a reader or writer blocks until the other side opens as well, a read blocks until somebody writes, and any side closes when the last one of the other side closes, i.e., last writer closes, the readers close as well and the other way around.
Assuming that is a correct undertanding, riddle me this: I have two processes. One is a bash script, the other a python. The bash script creates a fifo with mkfifo on disk and starts the python script in the background with the name to the fifo as parameter.
My python process has a main loop like this:
while True:
with open(fifo_path, 'r') as fifo:
for line in fifo:
line = line.strip()
if len(line) == 0:
continue
# code to handle line here ...
The bash script simplified does this:
mkfifo test.pipe
python myscript.py test.pipe &
# code ...
echo "foo" > test.pipe
# more code
echo "bar" > test.pipe
# ...
What should happen according to my understanding of pipes, the reading python script will hang in the open until the first echo (or more specifically the script) opens the pipe for writing. Then they will exchange the "foo" string and when the echo is done the pipe is closed which will cause the python script receive an EOF. However, the python script will proceed due to its loop to open again and everything will repeat.
What actually happens is that sometimes my bash script suddenly exits with exit code 141.
What I already have done to debug this:
- I verified that the python process is indeed running and not crashing. I have printed every error and added very generous try/except blocks to be sure I don't miss anything.
- Running the script with
bash -xseems to indicate that its indeed the echo that ends with code 141. - Googling and Stackoverflowing hinted me at 141 being SIGPIPE's under the hood that don't seem to be handled. If that is the case, I dont understand why they happen and how I should handle them. According to my understanding above they shouldn't occur.
- Intentionally opening the fifo a second time at the start of the python script and intentionally leaking the fd (never read from it)
Any hint is appreciated.