Subject: bug#6900: mktemp: want option to make a fifo

From: Paul Eggert <[email-masked]>
Date: Tue, 24 Aug 2010 11:32:49 -0700

On 08/24/2010 10:42 AM, John Reiser wrote:
 > Another case: "pipe" stderr into a separate pipeline from stdout.
 > This is useful for stderr as a status channel.
 >
 >      fifo_stderr1=$(mktemp --fifo stderr.XXXXXX)
 >      fifo_stderr2=$(mktemp --fifo stderr.XXXXXX)
 >      listener1<  $fifo_stderr1&
 >      listener2<  $fifo_stderr2&
 >      cmd1  2>  $fifo_stderr1  |  cmd2  2>  $fifo_stderr2

For this example, it's simpler (and does not use any more processes)
to follow Eric's suggestion to use mktemp -d to create a directory to
hold the named fifos, to put the named fifos in that directory, and
then to clean up with 'rm -r', with something like this:

   dir=$(mktemp -d dir.XXXXXX)
   mkfifo $dir/1 $dir/2
   listener1 < $dir/1
   listener2 < $dir/2
   cmd1 2> $dir/1 | cmd2 2> $dir/2

This mktemp -d version is easier to clean up after, as 'rm -fr $dir'
is easier to understand and read than 'rm -f $fifo_stderr1
$fifo_stderr1'.  The simplicity of cleanup becomes a greater advantage
as the number of named fifos (and other temporaries) grows.

Better yet, do not use named fifos, since pipes suffice:

   (cmd1 2>&1 >&3 | listener1) 3>&1 |
   (cmd2 2>&1 >&3 | listener2) 3>&1

Pipes are simpler and more robust, as they do not need 'rm'
afterwards, and you don't need to worry about what to do when mktemp
or mkfifo fails.

 > Another case: Use file descriptor 3 as a command and control channel.
 > Output has two default file descriptors (stdout and stderr), why not
 > input (stdin and cmdin)?  This is especially helpful for repairing a
 > nest of processes that are connected by pipes.
 >
 >     fifo_cmdin1=$(mktemp --fifo cmdin.XXXXXX); sleep 999000> 
$fifo_cmdin1&
 >     fifo_cmdin2=$(mktemp --fifo cmdin.XXXXXX); sleep 999000> 
$fifo_cmdin2&
 >     cmd1  3<  $fifo_cmdin1  |  cmd2  3<  $fifo_cmdin2&
 >     echo quit>  $fifo_cmdin1

Again, once things get this complicated, it doesn't cost any more
processes to use a temporary directory, with something like this:

   dir=$(mktemp -d dir.XXXXXX)
   mkfifo $dir/1 $dir/2
   listener1 < $dir/1
   listener2 < $dir/2
   cmd1 2> $dir/1 | cmd2 2> $dir/2

This example can also be simplified and made more robust by using
pipes instead of named fifos, as follows:

   (echo quit 1 | cmd1 3<&0 <&4) 4<&0 |
   (:           | cmd2 3<&0 <&4) 4<&0