Let's get back to the example of pipes, as it is quite interesting
and is also a good illustration of the links notion. When you use a
pipe in a command line, the shell creates the pipe for you
and operates so that the command before the pipe writes to it,
whereas the command after the pipe reads from it. All pipes,
whether they be anonymous
(like the ones used by the shells) or named
(see below) act like FIFOs (First In, First
Out). We already saw examples of how to use pipes in the
shell, but let's take one for the sake of our demonstration:
$ ls -d /proc/[0-9] | head -5
/proc/1/
/proc/2/
/proc/3/
/proc/4/
/proc/5/ |
One thing that you will not notice in this example (because it happens
too fast for one to see) is that writes on pipes are blocking. It means
that when the ls command writes to the pipe, it is
blocked until a process at the other end reads from the pipe. In order
to visualize the effect, you can create named pipes, which, as opposite
to the pipes used by shells, have names (i.e.: they are linked,
whereas shell pipes are not).
[1]
The command to create such pipes is mkfifo:
$ mkfifo a_pipe
$ ls -il
total 0
169 prw-rw-r-- 1 queen queen 0 Dec 10 14:12 a_pipe|
#
# You can see that the link counter is 1, and that the output shows
# that the file is a pipe ('p').
#
# You can also use ln here:
#
$ ln a_pipe the_same_pipe
$ ls -il
total 0
169 prw-rw-r-- 2 queen queen 0 Dec 10 15:37 a_pipe|
169 prw-rw-r-- 2 queen queen 0 Dec 10 15:37 the_same_pipe|
$ ls -d /proc/[0-9] >a_pipe
#
# The process is blocked, as there is no reader at the other end.
# Type C-z to suspend the process...
#
zsh: 3452 suspended ls -d /proc/[0-9] > a_pipe
#
# ...Then put in into the background:
#
$ bg
[1] + continued ls -d /proc/[0-9] > a_pipe
#
# now read from the pipe...
#
$ head -5 <the_same_pipe
#
# ...the writing process terminates
#
[1] + 3452 done ls -d /proc/[0-9] > a_pipe
/proc/1/
/proc/2/
/proc/3/
/proc/4/
/proc/5/
# |
Similarly, reads are also blocking. If we execute the above commands in
the reverse order, we observe that
head blocks,
waiting for some process to give it something to read:
$ head -5 <a_pipe
#
# Program blocks, suspend it: C-z
#
zsh: 741 suspended head -5 < a_pipe
#
# Put it into the background...
#
$ bg
[1] + continued head -5 < a_pipe
#
# ...And give it some food :)
#
$ ls -d /proc/[0-9] >the_same_pipe
$ /proc/1/
/proc/2/
/proc/3/
/proc/4/
/proc/5/
[1] + 741 done head -5 < a_pipe
$ |
You can also see an undesired effect in the previous example:
the
ls command has terminated before the
head command took over. The consequence is that you
got back at the prompt immediately, but
head
executed only after. Therefore, it made its output only after you got
back to the prompt.