The formal definition of pipe states that the STDOUT of the left file will be immediately piped to the STDIN of the right file.I have two files, hello.txt
and human.txt
. cat hello.txt
returns Hello
and cat human.txt
returns I am human
.Now if I do cat hello.txt | cat human.txt
, shouldn’t that return Hello I am human
?Instead I’m seeing command not found
.I am new to shell scripting.Can someone explain?
Advertisement
Answer
Background: A pipe arranges for the output of the command on the left (that is, contents written to FD 1, stdout) to be delivered as input to the command on the right (on FD 0, stdin). It does this by connecting the processes with a “pipe”, or FIFO, and executing them at the same time; attempts to read from the FIFO will wait until the other process has written something, and attempts to write to the FIFO will wait until the other process is ready to read.
cat hello.txt | cat human.txt
…feeds the content of hello.txt
into the stdin of cat human.txt
, but cat human.txt
isn’t reading from its stdin; instead, it’s been directed by its command line arguments to read only from human.txt
.
Thus, that content on the stdin of cat human.txt
is ignored and never read, and cat hello.txt
receives a SIGPIPE when cat human.txt
exits, and thereafter exits as well.
cat hello.txt | cat - human.txt
…by contrast will have the second cat
read first from stdin (you could also use /dev/stdin
in place of -
on many operating systems, including Linux), then from a file.