0

I want to make a named pipe that is always open for reading and writing.

So I typed this in to the terminal:

mkfifo testpipe
exec 3<> testpipe

All is working correct. But when I make a shell script with those commands it only makes a named pipe. Its not making it open for reading and writing.

Anyone know a solution?

Wild Man
  • 8,187
  • 4
  • 34
  • 44

2 Answers2

1

I can not completely see what you want to do, like using it in one or in multiple scripts - but I have an idea what went wrong:

To me, it looks like you were trying to combine two things, and combibing them got you in trouble:

Smells like deadlock

Opening a file on an extra file descriptor of the current shell:

$ exec 3<>file

And using a fifo special file:

$ mkfifo fifo
$ exec 3> fifo

And then, you tried to use them in a way that created a dead lock, for example waiting to finish writing, while you plan to read the data later - but never will get so far.

Both are powerful tools, but they are tricky to use together in a single shell script.


Examples

Here's the relevant example section from
Bash One-Liners Explained, Part III: All about redirections.

Note how thwo independent scripts are used in section 13 when working with the fifo:

  1. Open a file both for writing and reading

    $ exec 3<>file
    

Here we use bash's diamond operator <>. The diamond operator opens a file descriptor for both reading and writing.

So for example, if you do this:

$ echo "foo bar" > file   # write string "foo bar" to file "file".
$ exec 5<> file           # open "file" for rw and assign it fd 5.
$ read -n 3 var <&5       # read the first 3 characters from fd 5.
$ echo $var

This will output foo as we just read the first 3 chars from the file.

Now we can write some stuff to the file:

$ echo -n + >&5           # write "+" at 4th position.
$ exec 5>&-               # close fd 5.
$ cat file

This will output foo+bar as we wrote the + char at 4th position in the file.

  1. Send the output from multiple commands to a file

    $ (command1; command2) >file
    

This one-liner uses the (commands) construct that runs the commands a sub-shell. A sub-shell is a child process launched by the current shell.

So what happens here is the commands command1 and command2 get executed in the sub-shell, and bash redirects their output to file.

  1. Execute commands in a shell through a file

Open two shells. In shell 1 do this:

mkfifo fifo
exec < fifo

In shell 2 do this:

exec 3> fifo;
echo 'echo test' >&3

[ ... ]

Volker Siegel
  • 13,065
  • 5
  • 49
  • 65
0

If you make the script executable and run it like any other program, it is run in a new shell, so the pipe is opened in that shell, and then it exits, returning to your interactive shell that has not been affected. To have your shell interpret the script instead of executing a new shell to do it, you need to tell your current shell to open the file and interpret its contents using the source command. You can also use the shortcut ., as in . myscript.sh.

psusi
  • 37,551