As stated by @MelBoyce in his comment, this is because of the conceptual nature of a pipe. It has a input and an output, and you read the bytes from the output in the exact same order they were written into the input. Pipes are not common files or pointers, you're not suppose to read and write anywhere in it. You're forced to read the first bytes that entered the pipe and that never be read yet.
Pipes may be implemented as a buffer in memory, but the implementation could vary if in the future, if another more efficient way to do it is invented for example. However, the conceptual nature of the pipe won't change. You'll still use the same read(1)
and write(1)
system calls and they still behave the same. The file descriptors you get when you call pipe(1)
are used to force you to use the pipe correctly (and additionally provide some access control). That way, future modifications in the implementation won't break your code.
As for the cause, use strace
.
tail -f | strace bash >> foo
The second echo echo hello > pToB
gives me then this:
rt_sigprocmask(SIG_BLOCK, NULL, [], 8) = 0
read(0, "e", 1) = 1
read(0, "c", 1) = 1
read(0, "h", 1) = 1
read(0, "o", 1) = 1
read(0, " ", 1) = 1
read(0, "h", 1) = 1
read(0, "e", 1) = 1
read(0, "l", 1) = 1
read(0, "l", 1) = 1
read(0, "o", 1) = 1
read(0, "\n", 1) = 1
write(1, "hello\n", 6) = -1 EPIPE (Broken pipe)
--- SIGPIPE {si_signo=SIGPIPE, si_code=SI_USER, si_pid=3299, si_uid=1000} ---
+++ killed by SIGPIPE +++
So, the second time it tries to write hello\n, it gets a broken pipe error; that's why you can't read hello (it was never written), and bash quits so that's the end of it.
You'd have to use something that keeps the pipe open, I guess.
How about this?
(while read myline; do echo $myline; done) < pToP
For more background information, man 7 pipe
may be relevant, it describes the various error cases around pipes.
Best Answer
A process receives a SIGPIPE when it attempts to write to a pipe (named or not) or socket of type SOCK_STREAM that has no reader left.
It's generally wanted behaviour. A typical example is:
You don't want
find
to keep on running oncehead
has terminated (and then closed the only file descriptor open for reading on that pipe).The
yes
command typically relies on that signal to terminate.Will write "y" until some-command terminates.
Note that it's not only when commands exit, it's when all the reader have closed their reading fd to the pipe. In:
There will be 1 (the subshell), then 2 (subshell + sleep), then 1 (subshell) then 0 fd reading from the pipe after the subshell explicitely closes its stdin, and that's when
yes
will receive a SIGPIPE.Above, most shells use a
pipe(2)
whileksh93
uses asocketpair(2)
, but the behaviour is the same in that regard.When a process ignores the SIGPIPE, the writing system call (generally
write
, but could bepwrite
,send
,splice
...) returns with aEPIPE
error. So processes wanting to handle the broken pipe manually would typically ignore SIGPIPE and take action upon a EPIPE error.