15. Pipes
The stdout can also be connected to the stdin of a second command directly using the "|" (pipe) operator:
$ env | grep pa
OLDPWD=/home/pa
USER=pa
PWD=/home/pa/daten
HOME=/home/pa
The output of env is filtered by grep for lines containing the string "pa". A pipe may consist of many commands. So, a ranking of file types within a given sub tree can be done easily:
$ ls -R | egrep -o "\..*$" | sort | uniq -c | sort -n -r | head -5
349 .png
318 .txt
289 .au
208 .js
111 .html
ls -R
prints all directory entries of the current directory recursively to stdout. The grep command filters this output by lines which matches the regular expression: "\..*$". The pattern matches every file extension. "$" matches the end of a line. -o treats grep to print only the match to stdout. Uniq summarize the occurrence of the sorted list entries. sort -r -n
sorts the lines again, but numerically in descending order. The head command prints the first 5 lines. The exit status of the pipe is the exit status of the outer right command:
$ (exit 0) | (exit 254) | (exit 1)
$ echo $?
1
In conjunction to the anonymous pipe described above a named pipe, called fifo, exists. Fifos are created by the fifo command:
$ mkfifo fifo
A fifo is accessed by a path, but its content is always kept in memory. Writing to a fifo is done by:
$ echo "Oranges and lemons" > fifo
If no process is connected for reading the fifo blocks the writing process. It seems to hang until the fifo will be read by a second opened shell:
$ cat <fifo
Oranges and lemons
Even reading is blocked:
$ exec 4<fifo
until something is written to the fifo in the first shell:
$ echo "says the bells of St. Clement's" >fifo
It can be read now by:
$ cat <4
says the bells of St. Clement's