#!/bin/bash tmppipe=/tmp/temppipe mkfifo $tmppipe echo "test" > $tmppipe cat $tmppipe exit
Does not terminate. I assume that the cat command is waiting for an EOF from the pipe; how do I send one?
echo test > "$tmppipe" # BTW, you've got the quotes in the wrong places
that hangs. More precisely, it's the shell opening the pipe for writing before running
pipe are inter-process communication mechanisms, they are to be used between processes running concurrently. Here, the
>) will block until another process does an
open in read mode.
echo test > "$tmppipe" & cat < "$tmppipe"
will work because
cat run concurrently.
On Linux, you can get away with:
exec 3<> "$tmppipe" echo test >&3 cat < "$tmppipe" exec 3<&-
That works because read+write
<>) on pipes don't block on Linux, and because the
test\n output by
echo is small enough to fit in the pipe, so you can do the write and the read sequentially.
It wouldn't work for a larger output like:
exec 3<> "$tmppipe" seq 100000 >&3 cat < "$tmppipe" exec 3<&-
seq would fill up the pipe (64kiB in current versions of Linux) and block until some other process reads data off that pipe, which will never happen because
cat won't run until
seq has finished.
echo test 1<> "$tmppipe" cat < "$tmppipe"
would not work either because the
echo command line would open the pipe, write test and then close the pipe (and then the system would destroy it as there's no file descriptor open to it anymore). So the next
cat command line would try to instantiate a new pipe (and block until something opens the fifo file for writing).
Turns out the answer is obvious - the pipe is being locked by
echo, and never reaches cat!
Pipes do not store data. When a process attempts to write to a pipe, the write cannot complete until there is something attached to the other end of the pipe, to read it.
A way to solve this particular example, is to use
echo "test" > $tmppipe &
to make the writing process run in the background. That way it sits there any waits, while the script continues, until it reaches the
cat and can complete.