为什么我不能像在终端中那样在 bash 脚本中使用 exec 3>myfifo ?
我正在使用命名管道将 awk 过滤器变成一个简单的“服务器”,它应该能够从客户端获取文本输入,过滤它,并在 NUL 上刷新。
在终端 1 中,服务器运行如下:
$ 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;} /\0/ {fflush();}' <to_server >from_server;
echo "restarting...";
done
我有一个简单的脚本,应该将输入(以 NUL 结尾)放入输入管道,从输出管道读取,然后退出,而不向服务器发送 EOF(我们不希望服务器重新启动):
#!/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 '\0' >&3;
while read -rd '' <&4; do echo -n "$REPLY"; break; done;
现在,如果我在终端 2 执行$ echo This is wrong | bash client.sh
,我会This is correct
返回,但终端 1 显示服务器重新启动!但是,如果我从终端 2 中运行来自 client.sh 的命令,它不会重新启动。
它似乎与 exec 命令有关,因为我也可以
$ exec 3>to_server; exec 4<from_server;
$ echo "This is wrong" | sh client.sh
它不会重新启动。如果我那时
$ exec 3>&-; exec 4<&-
(当然会重新启动一次)并执行
$ echo "This is wrong" | sh client.sh
它每次都会重新启动。所以脚本中的 exec 命令似乎没有效果。但是,将ls /proc/$$/fd/
脚本中的 exec 命令放在后面表明它们确实指向正确的管道。
我在这里想念什么?