Introduction to Named Pipes
September 1st, 1997 by Andy Vaught in
One of the fundamental features that makes Linux and other Unices useful is the “pipe”. Pipes allow separate processes to communicate without having been designed explicitly to work together. This allows tools quite narrow in their function to be combined in complex ways.
A simple example of using a pipe is the command:
ls | grep x
When bash examines the command line, it finds the vertical bar character | that separates the two commands. Bash and other shells run both commands, connecting the output of the first to the input of the second. The ls program produces a list of files in the current directory, while the grep program reads the output of ls and prints only those lines containing the letter x.
The above, familiar to most Unix users, is an example of an “unnamed pipe”. The pipe exists only inside the kernel and cannot be accessed by processes that created it, in this case, the bash shell. For those who don't already know, a parent process is the first process started by a program that in turn creates separate child processes that execute the program.
The other sort of pipe is a “named” pipe, which is sometimes called a FIFO. FIFO stands for “First In, First Out” and refers to the property that the order of bytes going in is the same coming out. The “name” of a named pipe is actually a file name within the file system. Pipes are shown by ls as any other file with a couple of differences:
% ls -l fifo1 prw-r--r-- 1 andy users 0 Jan 22 23:11 fifo1|
The p in the leftmost column indicates that fifo1 is a pipe. The rest of the permission bits control who can read or write to the pipe just like a regular file. On systems with a modern ls, the | character at the end of the file name is another clue, and on Linux systems with the color option enabled, fifo| is printed in red by default.
On older Linux systems, named pipes are created by the mknod program, usually located in the /etc directory. On more modern systems, mkfifo is a standard utility. The mkfifo program takes one or more file names as arguments for this task and creates pipes with those names. For example, to create a named pipe with the name pipe1 give the command:
mkfifo pipe
The simplest way to show how named pipes work is with an example. Suppose we've created pipe as shown above. In one virtual console1, type:
ls -l > pipe1and in another type:
cat < pipeVoila! The output of the command run on the first console shows up on the second console. Note that the order in which you run the commands doesn't matter.
If you haven't used virtual consoles before, see the article “Keyboards, Consoles and VT Cruising” by John M. Fisk in the November 1996 Linux Journal.
If you watch closely, you'll notice that the first command you run appears to hang. This happens because the other end of the pipe is not yet connected, and so the kernel suspends the first process until the second process opens the pipe. In Unix jargon, the process is said to be “blocked”, since it is waiting for something to happen.
One very useful application of named pipes is to allow totally unrelated programs to communicate with each other. For example, a program that services requests of some sort (print files, access a database) could open the pipe for reading. Then, another process could make a request by opening the pipe and writing a command. That is, the “server” can perform a task on behalf of the “client”. Blocking can also happen if the client isn't writing, or the server isn't reading.
Create two named pipes, pipe1 and pipe2. Run the commands:
echo -n x | cat - pipe1 > pipe2 & cat <pipe2 > pipe1
On screen, it will not appear that anything is happening, but if you run top (a command similar to ps for showing process status), you'll see that both cat programs are running like crazy copying the letter x back and forth in an endless loop.
After you press ctrl-C to get out of the loop, you may receive the message “broken pipe”. This error occurs when a process writing to a pipe when the process reading the pipe closes its end. Since the reader is gone, the data has no place to go. Normally, the writer will finish writing its data and close the pipe. At this point, the reader sees the EOF (end of file) and executes the request.
Whether or not the “broken pipe” message is issued depends on events at the exact instant the ctrl-C is pressed. If the second cat has just read the x, pressing ctrl-C stops the second cat, pipe1 is closed and the first cat stops quietly, i.e., without a message. On the other hand, if the second cat is waiting for the first to write the x, ctrl-C causes pipe2 to close before the first cat can write to it, and the error message is issued. This sort of random behavior is known as a “race condition”.
Bash uses named pipes in a really neat way. Recall that when you enclose a command in parenthesis, the command is actually run in a “subshell”; that is, the shell clones itself and the clone interprets the command(s) within the parenthesis. Since the outer shell is running only a single “command”, the output of a complete set of commands can be redirected as a unit. For example, the command:
(ls -l; ls -l) >ls.out
writes two copies of the current directory listing to the file ls.out.
Command substitution occurs when you put a < or > in front of the left parenthesis. For instance, typing the command:
cat <(ls -l)
results in the command ls -l executing in a subshell as usual, but redirects the output to a temporary named pipe, which bash creates, names and later deletes. Therefore, cat has a valid file name to read from, and we see the output of ls -l, taking one more step than usual to do so. Similarly, giving >(commands) results in Bash naming a temporary pipe, which the commands inside the parenthesis read for input.
If you want to see whether two directories contain the same file names, run the single command:
cmp <(ls /dir1) <(ls /dir2)
The compare program cmp will see the names of two files which it will read and compare.
Command substitution also makes the tee command (used to view and save the output of a command) much more useful in that you can cause a single stream of input to be read by multiple readers without resorting to temporary files—bash does all the work for you. The command:
ls | tee >(grep foo | wc >foo.count) \
>(grep bar | wc >bar.count) \
| grep baz | wc >baz.count
counts the number of occurrences of foo, bar and baz in the output of ls and writes this information to three separate files. Command substitutions can even be nested:
cat <(cat <(cat <(ls -l))))works as a very roundabout way to list the current directory.
As you can see, while the unnamed pipes allow simple commands to be strung together, named pipes, with a little help from bash, allow whole trees of pipes to be created. The possibilities are limited only by your imagination.
Special Magazine Offer -- 2 Free Trial Issues!
Receive 2 free trial issues of Linux Journal as well as instant online access to current and past issues. There's NO RISK and NO OBLIGATION to buy. CLICK HERE for offer
Linux Journal: delivering readers the advice and inspiration they need to get the most out of their Linux systems since 1994.
Sorry, offer available in the US only. International orders, click here.
Subscribe now!
The Latest
Featured Videos
Email is one of the least private and least secure forms of communication, although few people realize this. MixMaster is one way to allow secure, anonymous communication even over the very public medium of email. This tutorial will get you started with MixMaster quickly and easily.
In case you were wondering about the fun side of Linux World Expo, we thought we'd give you a peek at our shenanigans. We at Linux Journal love what we do so much, that we can't help but have a ball wherever we go.
Recently Popular
From the Magazine
September 2008, #173
Feeling a bit like a Thermian? Never give up, never surrender! Someday, you could go from underdog to top dog. Just take a look at a few of the underdogs we highlight in this issue: Mutt, djbdns, Nginix, Gentoo, Xara and the program voted mostly likely to fail just a few years back—Firefox. If Firefox is not radical enough for you, check out Chef Marcel's column for some more alternatives. Having trouble mapping your program data to your relational database? If so, Rueven Lerner shows you some tricks in his At The Forge column.
Need to run GUI applications on your server in the next state? In his Paranoid Penguin column, Mick Bauer shows you how to do it securely. Kyle Rankin keeps hacking and slashing and shows you a few split screen secrets you may not be familiar with. Finally, we all know what happens next February, but only Doc knows what happens afterward.

Delicious
Digg
Reddit
Newsvine
Technorati







Also works with cygwin
On April 14th, 2008 Chris Bruner (not verified) says:
If you have cygwin installed, you can try out this article. Works great.
A slight typo in the first example
mkfifo pipe
The simplest way to show how named pipes work is with an example. Suppose we've created pipe as shown above. In one virtual console1, type:
ls -l > pipe1
and in another type:
cat < pipe
the ls -l > pipe1 should be ls -l > pipe
10 years later still a great article
On December 14th, 2007 davedoom (not verified) says:
After 10 years i still glance at this article from time to time. Andy Vaught if you are still out there, you have made an impact.
ditto here. timeless
On March 29th, 2008 pipemaster (not verified) says:
ditto here. timeless article. btw, my eyes hurt from having to figure out the captcha.
Named Pipes; A great article!
On February 18th, 2008 Rajendra Uppal (not verified) says:
simplicity with genious, a powerful combination. A great piece of work.
thanks & regards.
I also wanna say something!
On February 20th, 2008 Rajendra Uppal (not verified) says:
have a look at:
http://rajen.iitd.googlepages.com/rajendrauppal
named pipes
On October 31st, 2007 Anonymous (not verified) says:
Linux code for a client/server program using named pipes to sare some data between clients through a server
Thank u..it really helped me
On September 19th, 2007 Narcissa (not verified) says:
Thank u..it really helped me a lot.
Thanks
On July 10th, 2008 Jeffman (not verified) says:
Thank you for having published.
Voyance gratuite
Great
On August 6th, 2008 Anonymous (not verified) says:
Yes it's a great post
Voyance
named pipes
On September 10th, 2007 kanchan (not verified) says:
How to use the named pipes for conversation between 2 processes?
Please write the program for me.
What i do not understand is
On August 14th, 2007 guhnoo (not verified) says:
What i do not understand is the following:
When i do
mkfifo pipe pipe2; echo foo >pipe & cat pipe >pipe2 & cat < pipe2 >pipe
it sends the foo back and forth and i get a high cpu, however when I do
mkfifo pipe pipe2; echo foo >pipe & cat pipe >pipe2 & cat pipe2 >pipe
my cpu doesn't raise, so the foo isn't send back and forth. My question is:
why doesn't the latter work? does cat pipe2 >pipe differ from cat < pipe2 >pipe ?
Hey, thanks for the article.
On May 30th, 2007 Anonymous (not verified) says:
Hey, thanks for the article. It was really helpful.
Brilliant info
On August 15th, 2007 SeHe (not verified) says:
I second all the commenters: highly informative stuff. It lead me to the following gem, after having spent 2 days looking into perl modules, C++ libraries and even rsynclib to do streaming diffs on fifos:
diff -ur <(xxd pop.sig) <(xxd pop2.sig) | kompare -o -
Cheers
But ... no sigar
On May 30th, 2008 Sehe (not verified) says:
Today I found out that it is not actually streaming (because of the non-linear nature of diff(1))
This woke me up:
sehe@sehe-desktop:~$ diff -Ewbur <(xxd /dev/dvdrw1) <(ssh koolu xxd /dev/dvdrw)
diff: memory exhausted
good information regarding pipes in unix
On May 22nd, 2007 Amol (not verified) says:
good information regarding pipes, parathesis of commands, use of tee command
Thank you very much
On March 31st, 2007 juacompe (not verified) says:
This is really useful resource. Thanks!
Difference between mknod and mkfifo function
On February 15th, 2007 Anonymous (not verified) says:
What is the difference between mknod and mkfifo command?
A good article
On September 20th, 2006 Imran (not verified) says:
Hi,
A nice article on pipes.
I have a few questions here.
1)How to flush stdio buffers associated with the pipe.
2)What happens when there is no space on the pipe to accomodate the flushed data of the stdio buffer?
Imran
as seen in bash 3
On October 27th, 2006 vince^II (not verified) says:
Have a look here:
http://en.wikipedia.org/wiki/Bash#I.2FO_redirection
# close FD6
exec 6>&-
Problem using named pipes in a shell script
On June 22nd, 2006 Jim Wings (not verified) says:
I am having a problem with using named pipes in a shell script (ksh or borne shell). As a test do something like this:
----------- cut --------
#!/bin/ksh
# This is shell script: "read_pipe"
mkfifo /tmp/event_pipe
while true
do
read EVENT </tmp/event_pipe
echo $EVENT >>/tmp/event.log
done
----------- cut -------------
Run the script via: "nohup read_pipe &".
Do something like: "cat /etc/passwd >/tmp/event_pipe". You will get some of the password file in the "/tmp/event.log", but not all of it. I tried various ways of doing the "read", but still get the same results. If I send data slowly (sleep 1 second between each line of data) it works. So what am I doing wrong? I tried a loop with "tail -f /tmp/event_pipe | while read EVENT", still the same result.
The purpose of "read_pipe" script when it does "real work", will be to process each "line" of data as it comes in. I don't know how fast the lines of data will come in, and I am afraid I will miss lines, based on the testing I did with "cat /etc/passwd". It almost appears I am overloading the "named pipe" and it is not blocking correctly. Anyone done something like this? Any ideas? Thanks.
RE: Problem using named pipes in a shell script
On June 5th, 2007 E. Choroba (not verified) says:
Try crumble your loop into two loops:
while true
do
cat /tmp/event_pipe | while read line
do echo $line >> /tmp/event.log
done
done
Or use
exec 3< /tmp/event_pipeandread -u3.How do we keep the stream from closing?
On July 4th, 2006 Jean D. Fongang (not verified) says:
Thanx for your very infromative article. We can only find this kind of stuff on LJ.
I have been trying for sometime to keep the mysql client connected after executing a SQL script, and the words "named pipes" just poped to my mind. However, although I managed to put it to use in some scenarios, I fail to keep the stream flowing.
on the first shell I do this:
linux:/var/lib/mysql/replMySQL # mysql -u root -p1234 < pipe1
linux:/var/lib/mysql/replMySQL #
As soon as I do
linux:/var/lib/mysql/replMySQL # echo 'FLUSH TABLES WITH READ LOCK;' > pipe1
on the second shell, the mysql client sees the EOF, executes and exits.
My actual problem is to keep the mysqlclient connected after the 'FLUSH TABLES WITH READ LOCK;', so that I can do a certified backup from within a script and then release the connection and the lock. This script will be part of a solution in which I might not be able to put python or perl.
Keeping the stream open
On July 26th, 2007 Anonymous (not verified) says:
Apparently, the stream closes when all writers have closed, so to keep the stream from closing open another writer that doesn't actually write anything. There must be better examples, but the following will work:
sleep 999999999 > pipe1 &
Yup.
On May 29th, 2006 Robert Persson (not verified) says:
Yup. Very good article. Clear and simple.
This was quite helpful. I
On May 21st, 2006 Anonymous (not verified) says:
This was quite helpful. I was wondering however if there was a way to keep a process attached to a pipe permanently. When I used the above examples, the output process worked just fine for one command and then needed to be reattached. I'll keep researching and write back if I find anything on my own.
The answer is yes. I
On May 22nd, 2006 Anonymous (not verified) says:
The answer is yes. I solved my problem with:
tail -f <name_of_pipe> | <process_to_handle_output> &
Re: How do we keep the stream from closing?
On July 4th, 2006 Jean D. Fongang (not verified) says:
how can be the mysql client in this case? It didn't work.
still useful :D
On May 1st, 2006 Anonymous (not verified) says:
9 years later... Still useful :)
Thanks you for sharing Named-Pipe Knowledge, very useful
On February 25th, 2006 chen xueqin (not verified) says:
I understand well and like it
Very useful!!!!
On January 5th, 2006 Riccardo (not verified) says:
many thanks for sharing your knowledge so clearly!
Awesome, thank you!
On November 30th, 2005 Kaolin Fire (not verified) says:
I wanted to give C-Kermit a dynamic list of files to upload (using svn diff), and (as above) "named pipe" somehow popped into my head as maybe something I could use. I'd never sat down to figure them out, and _magic_!
Re: Linux Apprentice: Introduction to Named Pipes
On September 2nd, 2004 Anonymous says:
Andy, your little article here really gives the gist of it. Thank you
Re: Linux Apprentice: Introduction to Named Pipes
On September 1st, 2004 Anonymous says:
This articles rocks!
Re: Linux Apprentice: Introduction to Named Pipes
On March 17th, 2004 Anonymous says:
it is really very helpful for me. thanks a lot
Re: Named Pipes YOUR CODE IS BAD
On February 29th, 2004 Anonymous says:
Your code with ls and tee is wrong. It gives:
Missing name for redirect.
Fix it.
try using bash!!!
On February 16th, 2007 Anonymous (not verified) says:
try using bash!!!
Re: Named Pipes
On August 1st, 2004 Anonymous says:
the code with ls and tee works for me. I suggest that you stop shouting and check that you copied it correcly when you tried it. And that you're really running bash.
Re: Linux Apprentice: Introduction to Named Pipes
On September 6th, 2003 Anonymous says:
I agree with the former reader - a great article about a great feature of unix!
Re: Linux Apprentice: Introduction to Named Pipes
On October 15th, 2003 Anonymous says:
nice article indeed ...
Re: Linux Apprentice: Introduction to Named Pipes
On April 4th, 2002 Anonymous says:
Thanks a lot it helped me a lot to understand named pipes
Very helpful. Thanks.
On September 2nd, 2005 cevher (not verified) says:
Very helpful.
Thanks.
Doesn't work for me ;(
On December 15th, 2007 Anonymous (not verified) says:
Doesn't work in Windows 2000 cmd shell for me. This linux stuff is for the birds.
Thanks indeed
On October 26th, 2005 zzen (not verified) says:
I needed to replace a filename parameter with command output, without taking up the stdin, but had no idea how. By some unknown magic, the phrase "named pipe" sprung to my mind. I googled for it, your article came up first, it was very clear, brief and informative - and ultimately helped me solve my problem in a few minutes. Thanks!