Search code examples
bashnamed-pipes

Why "exec 7<>$tmp_file" makes named pipe write non-blocking?


I'm new to bash script programming and I'm trying to understand the code below:

tmp_file=/tmp/tmp_file$$
mkfifo $tmp_file
echo "msg_A" >$tmp_file # blocks, since pipe is unbuffered and no one is reading from it
read msg <$tmp_file
echo $msg
tmp_file=/tmp/tmp_file$$
mkfifo $tmp_file

exec 7<>$tmp_file # add this line

echo "msg_A" >$tmp_file # now, the write operation won't block, why?
read msg <$tmp_file
echo $msg  # msg_A is printed

I want to know what does exec 7<>$tmp_file do in the code example above, and why adding this line makes the write operation non-blocking?


Solution

  • I want to know what does exec 7<>$tmp_file do in the code example above, and why adding this line makes the write operation non-blocking?

    It doesn't. That exec command opens $tmp_file (which resolves to the name of a FIFO) for reading and writing, and leaves it open, associated with file descriptor number 7 (within that execution of the script).

    The other relevant part of the code example is this:

    echo "msg_A" >$tmp_file # blocks, since pipe is unbuffered and no one is reading from it
    

    ... and you have a bit of a misunderstanding about it. It is not the write to the FIFO that blocks without the exec. Rather, it is the shell's attempt to open the FIFO in the first place, which happens before any part of echo itself runs. See Linux named pipes: not as FIFO as thought over at Unix & Linux SE. (Though that question asks about Linux specifically, the FIFO semantics described are pretty common among Unix-family OSes.)

    After the exec opens the FIFO for both reading and writing, until that file descriptor is closed, any process with sufficient permissions can open the FIFO for either reading or writing without blocking.