Differences between revisions 2 and 11 (spanning 9 versions)
Revision 2 as of 2007-09-09 08:33:33
Size: 448
Editor: ppp073-116
Comment: uh ? what is this faq about
Revision 11 as of 2009-12-07 14:22:42
Size: 1610
Editor: GreyCat
Comment: fix whitespace
Deletions are marked like this. Additions are marked like this.
Line 1: Line 1:
[[Anchor(faq85)]]
== How do I prevent a named pipe from closing? ==
<<Anchor(faq85)>>
== How to write several times to a fifo without having to reopen it? ==
The basic use of NamedPipes is:
Line 4: Line 5:
We've found two ways so far:

 * Using a loop
  {{{
  while cat myfifo; do :; done}}}

 * Using tail
  {{{
  tail -n +1 -f myfifo}}}

What problem are you trying to solve?
Open a program that reads the pipe and send the output of several commands to it?
like:
Line 20: Line 8:
echo 'a' > myfifo
}}}
This works, but `cat` dies after reading one line. (In fact, what happens is each time the named pipe is closed by the ''writer'', this signals an end of file condition for the ''reader''. So `cat`, the reader, terminates because it saw the end of its input.)

What if we want to write several times to the pipe without having to restart the reader? We have to arrange for all our data to be sent without opening and closing the pipe multiple times.

If the commands are consecutive, they can be grouped:

{{{
cat < myfifo &
{ echo 'a'; echo 'b'; echo 'c'; } > myfifo
}}}
The use of `tail -f` instead of `cat` can be an option:

{{{
tail -f myfifo &

echo 'a' > myfifo
# Doesn't die
echo 'b' > myfifo
echo 'c' > myfifo
}}}
The problem here is that the process `tail` doesn't die, even if the named pipe is deleted. In a script this is not a problem as you can kill `tail` on exit. There is also the --pid option to tail that can prove useful in some cases.

But if they can't be grouped for some reason or if the use of` tail` is not an option, a better way is to assign a file descriptor to the pipe and write there:

{{{
cat < myfifo &

# assigning fd 3 to the pipe
Line 21: Line 39:
echo blah >&3
echo more blah >&3

# writing to fd 3 instead of reopening the pipe
echo 'a' >&3
echo 'b' >&3
echo 'c' >&3

# closing the fd
Line 24: Line 47:
}}} }}}
Closing the fd causes the pipe's reader to receive the end of file indication.

How to write several times to a fifo without having to reopen it?

The basic use of NamedPipes is:

mkfifo myfifo
cat < myfifo &
echo 'a' > myfifo

This works, but cat dies after reading one line. (In fact, what happens is each time the named pipe is closed by the writer, this signals an end of file condition for the reader. So cat, the reader, terminates because it saw the end of its input.)

What if we want to write several times to the pipe without having to restart the reader? We have to arrange for all our data to be sent without opening and closing the pipe multiple times.

If the commands are consecutive, they can be grouped:

cat < myfifo &
{ echo 'a'; echo 'b'; echo 'c'; } > myfifo

The use of tail -f instead of cat can be an option:

tail -f myfifo &

echo 'a' > myfifo
# Doesn't die
echo 'b' > myfifo
echo 'c' > myfifo

The problem here is that the process tail doesn't die, even if the named pipe is deleted. In a script this is not a problem as you can kill tail on exit. There is also the --pid option to tail that can prove useful in some cases.

But if they can't be grouped for some reason or if the use of tail is not an option, a better way is to assign a file descriptor to the pipe and write there:

cat < myfifo &

# assigning fd 3 to the pipe
exec 3>myfifo

# writing to fd 3 instead of reopening the pipe
echo 'a' >&3
echo 'b' >&3
echo 'c' >&3

# closing the fd
exec 3>&-

Closing the fd causes the pipe's reader to receive the end of file indication.

BashFAQ/085 (last edited 2016-10-17 20:45:47 by 163-172-21-117)