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