Named pipes in the shell
In the last post – Pipes in the shell – I wrote about regular, unnamed pipes in the shell. Now I want to continue that story with a little introductory to a related topic — named pipes in unix. They are not as useful or versatile as their unnamed friends, but sometimes they can help you a lot.
A named pipe is very similar to an unnamed pipe. It also connects the output of one command to the input of the second command. But, a named pipe is also very similar to a file, as it is saved in the file system. To create such a pipe we need to use the mkfifo
command, where the fifo part signifies that it is a – first in, first out – kind of buffer.
cd /tmp
mkfifo testpipe1
Filtering files by their title #
With an unnamed pipe I could list all the files in a directory that had the string “cat” in their title
ls -l | grep "cat"
With a named pipe I can do the same using the previously created testpipe1
named pipe
grep "cat" < testpipe1
ls -l > testpipe1
But, in the name of science, why would anyone ever use a two line command with a harder to understand logic rather then a simple one liner that you can write using just a regular pipe. The answer is simple — I can separate the filter logic from it’s source. In other words I can just write out the grep
filter and then navigate to the directory I want to list out.
grep "cat" < testpipe1 &
cd /home/pipeuser/animals/
ls -l > /tmp/testpipe1
Notice that I had to run the pipe’s filter as a background job so that I can continue to work in the same shell. A different approach, that I use frequently, is to open two seperate terminals and execute the filter part in the first terminal, and the source part in the other.
A nice example #
Using the nc
command we can create a one liner proxy in the shell. The following command will redirect all the request from port 12345 to Google and send back the response using the named pipe we have already created above
nc -l 12345 0<testpipe1 | nc www.google.com 80 1>testpipe1