"read" command waiting for additional newline if input comes through pipe
Solution 1:
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 noread
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 aSIGPIPE
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.