echo "hello world" | cat
cat < echo "hello world"
does not? My (incorrect) intuition is that pipe would redirect
We have two similar but different things
echo "hello world" | cat # This is a pipeline
The pipe control operators (
|&) connect the output of a command to the input of the following one in the pipeline. So the first example works, the output of the
echo command, "Hello word", is connected with the input of the following
cat command, that assumes the standard input as input file if not else specified. Indeed we can read from
cat - concatenate files and print on the standard output
and below the example with the simple invocation of
cat Copy standard input to standard output
A redirection, or better an attempt of input redirection
cat < echo "hello world" # This is an attempt of redirection
In this case
cat command is taking its input from the standard input that you redirect with the operator
< from the file on the right side of
<... that is not a file. This is because it doesn't work.
From the redirection section of the
Redirection of input causes the file whose name results from the expansion of word to be opened for reading on file descriptor n, or the standard input (file descriptor 0) if n is not specified.
In bash it works for different reasons
cat <(echo "hello world") Process Substitution
Process substitution is supported on systems that support named pipes (FIFOs) or the /dev/fd method of naming open files. It takes the form of
>(list). The process list is run with its input or output connected to a FIFO or some file in
/dev/fd. The name of this file is passed as an argument to the current command as the result of the expansion. If the
>(list)form is used, writing to the file will provide input for list. If the
<(list)form is used, the file passed as an argument should be read to obtain the output of list.
cat <<< $(echo "hello world") Here Strings
The word undergoes brace expansion, tilde expansion, parameter and variable expansion, command substitution, arithmetic expansion, and quote removal. Path-name expansion and word splitting are not performed. The result is supplied as a single string to the command on its standard input.
man bashand search for redirection, pipeline, Here Strings and Process substitution
man catjust because we use it...
That stream reads from files.
> is out to a file and
< is in from a file. Demonstration:
echo "HELLO HELLO HELLO" > HELLO.txt and then
cat < HELLO.txt gets you output
HELLO HELLO HELLO
Kinda useless since the output already goes where you'd want, but another example with the same HELLO.txt is
cat < HELLO.txt >&1 explicitly directing
cat's output to STDOUT.
More usefully, you sometimes find file descriptor 2's output (STDERR) being redirected with commands like
grep somepattern /path/to/a_bunch_of_files/* 2>&1 >> alloutput.txt
2>&1 stream directs errors to standard output. Then all standard output is streamed to alloutput.txt. This would put error output in the file with standard output.