Why can't I use exec 3>myfifo in the same manner in a bash script as I can in my terminal?
I'm using named pipes to turn an awk filter into a simple "server", that should be able to take text input from clients, filter it, and flush on NUL.
In terminal 1, the server is running like this:
$ mkfifo to_server from_server;
$ while true; do
# Really, this awk script BEGIN's with reading in a huge file,
# thus the client-server model
awk '{sub("wrong", "correct");print;} // {fflush();}' <to_server >from_server;
echo "restarting...";
done
And I've got a simple script that should put input, ending with a NUL, into the input-pipe, and read from the output pipe, and then exit, without sending an EOF to the server (we don't want the server to restart):
#!/bin/bash
# According to http://mywiki.wooledge.org/BashFAQ/085 , using
# `exec 3>mypipe; echo foo >&3;` instead of `echo foo >mypipe`
# should ensure that the pipe does not get the EOF which closes it:
exec 3>to_server;
exec 4<from_server;
cat >&3;
echo -e '' >&3;
while read -rd '' <&4; do echo -n "$REPLY"; break; done;
Now, if I in terminal 2 do $ echo This is wrong | bash client.sh
, I get This is correct
back, but terminal 1 shows me that the server restarts! If I run the commands from client.sh from within terminal 2, however, it does not restart.
It seems to be related to the exec commands, since I can also do
$ exec 3>to_server; exec 4<from_server;
$ echo "This is wrong" | sh client.sh
and it does not restart. If I then
$ exec 3>&-; exec 4<&-
(which of course restarts it once) and do
$ echo "This is wrong" | sh client.sh
it restarts every time. So it seems the exec commands in the script have no effect. However, putting ls /proc/$$/fd/
after the exec commands in the script shows that they do in fact point to the correct pipes.
What am I missing here?
See Question&Answers more detail:
os