Suppose you have this script, on an Ubuntu machine:
#!/bin/env python3
import sys
import time
try:
i = 1
while True:
print(i)
i += 1
except Exception as e:
sys.stderr.write(f"We caught an exception {e!r}\n")
sys.stderr.flush()
while True:
sys.stderr.write("Sleeping for a minute\n")
sys.stderr.flush()
time.sleep(60)
And you run it like this:
# ./some_test.py | head -n 10
1
2
3
4
5
6
7
8
9
10
We caught an exception BrokenPipeError(32, 'Broken pipe')
Sleeping for a minute
Sleeping for a minute
.
.
.
And it will not stop, of course. Is there a way in which, from the outside, we can see that the output stream is closed? I checked with lsof and and also fds in /proc and I do not see anything that makes me think that the stream is closed even though I know that the pipe is broken and the exception when it tried to write also says so:
# lsof -p 28466
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
python3 28466 root cwd DIR 252,3 4096 132 /root
python3 28466 root rtd DIR 252,3 4096 128 /
python3 28466 root txt REG 252,3 5904904 9540 /usr/bin/python3.10
python3 28466 root mem REG 252,3 5712144 33793209 /usr/lib/locale/locale-archive
python3 28466 root mem REG 252,3 2220400 50352186 /usr/lib/x86_64-linux-gnu/libc.so.6
python3 28466 root mem REG 252,3 108936 50422136 /usr/lib/x86_64-linux-gnu/libz.so.1.2.11
python3 28466 root mem REG 252,3 194872 50417841 /usr/lib/x86_64-linux-gnu/libexpat.so.1.8.7
python3 28466 root mem REG 252,3 940560 50413373 /usr/lib/x86_64-linux-gnu/libm.so.6
python3 28466 root mem REG 252,3 27002 50386759 /usr/lib/x86_64-linux-gnu/gconv/gconv-modules.cache
python3 28466 root mem REG 252,3 240936 50359529 /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
python3 28466 root 0u CHR 136,3 0t0 6 /dev/pts/3
python3 28466 root 1w FIFO 0,13 0t0 110475 pipe
python3 28466 root 2u CHR 136,3 0t0 6 /dev/pts/3
# ls -l /proc/28466/fd
total 0
lrwx------ 1 root root 64 Oct 20 13:44 0 -> /dev/pts/3
l-wx------ 1 root root 64 Oct 20 13:44 1 -> 'pipe:[110475]'
lrwx------ 1 root root 64 Oct 20 13:44 2 -> /dev/pts/3