It doesn't have anything to do with the newline.
If you run your command using strace
, you will find out that the cat
will receives a SIGPIPE
at the end, before being closed:
$ strace cat | read
...
someOutput
...
+++ killed by SIGPIPE +++
- First
cat
command gets to run .
- Then you type something in for the first time and hit the Enter.
- What you have typed will be piped to the
read
.
cat
is still running and waiting for a EOF.
- You type something else and then hit the Enter agian.
This time, it can't be piped to read
, because there is no read
anymore waiting for input (it has been closed after first pipe) unless you run it like this:
cat | while read line; do echo $line; done;
cat
will receives a SIGPIPE
and gets closed.
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. [1]
Receiving SIGPIPE
happens after when second pipe happens.
For example consider yes
command, because a command like yes
pipes something fast and repeatedly:
yes | read
it gets closed immediately after the second pipe, pay attention to the two write()
calls:
close(3) = 0
write(1, "y\ny\ny\ny\ny\ny\ny\ny\ny\n"..., 8192) = 8192
write(1, "y\ny\ny\ny\ny\ny\ny\ny\ny\n"..., 8192) = -1 EPIPE (Broken pipe)
--- SIGPIPE {si_signo=SIGPIPE, si_code=SI_USER, si_pid=3542, si_uid=1000} ---
+++ killed by SIGPIPE +++
Although, because yes
command is too fast you might see more than of two write()
calls, however if you run it several times you will see at least two calls and never one.
cat
only tries to send whole lines through the pipe as soon as the ENTER key gets pressed.read
exits after the first line already, butcat
only notices that when it tries to use the pipe again, not earlier? – Byte Commander Sep 02 '17 at 09:33SIGPIPE
and get closed. – Ravexina Sep 02 '17 at 09:36cat
actually isn't line buffered at all: https://superuser.com/a/896684/418736 - now I'm confused. – Byte Commander Sep 02 '17 at 09:45strace cat | read
? Or runningstrace cat
and sending a SIGPIPE (kill -13
) to its PID? I'm not sure about the buffering, but from inspecting thestrace
outputs, that is how it's working. – Ravexina Sep 02 '17 at 09:59cat
should not do that. I don't know. – Byte Commander Sep 02 '17 at 10:12cat <whatever> | grep ^ --line-buffered
and use it in place ofcat
. – Sep 02 '17 at 10:55