我想创建一个始终开放以供读写的命名管道。
因此我在终端中输入了以下代码:
mkfifo testpipe
exec 3<> testpipe
一切正常。但是当我使用这些命令创建 shell 脚本时,它只会创建一个命名管道。它不会使其打开以供读写。
有人知道解决办法吗?
答案1
我不能完全明白你想做什么,比如在一个或多个脚本中使用它 - 但我知道出了什么问题:
对我来说,看起来你试图将两件事结合起来,而将它们结合起来给你带来了麻烦:
闻起来像僵局
在当前 shell 的额外文件描述符上打开文件:
$ exec 3<>file
使用 fifo 特殊文件:
$ mkfifo fifo
$ exec 3> fifo
然后,您尝试以一种产生死锁的方式使用它们,例如等待写入完成,而您计划稍后读取数据 - 但永远不会走到这一步。
两者都是功能强大的工具,但是在单个 shell 脚本中一起使用比较棘手。
例子
以下是相关示例部分
Bash 单行命令详解,第三部分:重定向。
请注意第 13 节中如何使用两个独立的脚本来处理 fifo:
打开文件以进行写入和读取
$ exec 3<>file
这里我们使用 bash 的菱形运算符 <>。菱形运算符打开一个文件描述符,用于读写。
例如,如果你这样做:
$ 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
这将输出 foo,因为我们刚刚从文件中读取了前 3 个字符。
现在我们可以向文件中写入一些内容:
$ echo -n + >&5 # write "+" at 4th position. $ exec 5>&- # close fd 5. $ cat file
这将输出 foo+bar,因为我们在文件的第 4 个位置写入了 + 字符。
将多个命令的输出发送到文件
$ (command1; command2) >file
此单行代码使用 (commands) 结构来运行子 shell 中的命令。子 shell 是由当前 shell 启动的子进程。
所以这里发生的情况是命令 command1 和 command2 在子 shell 中执行,并且 bash 将它们的输出重定向到文件。
- 通过文件在 shell 中执行命令
打开两个 shell。在 shell 1 中执行以下操作:
mkfifo fifo exec < fifo
在 shell 2 中执行以下操作:
exec 3> fifo; echo 'echo test' >&3
[...]
答案2
如果您使脚本可执行并像其他程序一样运行它,它将在新 shell 中运行,因此管道将在该 shell 中打开,然后退出并返回未受影响的交互式 shell。要让您的 shell 解释脚本而不是执行新 shell 来执行此操作,您需要告诉当前 shell 使用命令打开文件并解释其内容source
。您也可以使用快捷方式.
,如. myscript.sh
。