有人可以在Linux中发布一个在Bash中使用命名管道的简单示例吗?
答案 0 :(得分:83)
实际使用命名管道的最佳示例之一...
来自http://en.wikipedia.org/wiki/Netcat:
另一个有用的行为是使用
netcat
作为代理。端口和主机都可以重定向。看看这个例子:nc -l 12345 | nc www.google.com 80
端口12345代表请求。
这将在端口12345上启动
nc
服务器,并且所有连接都会重定向到google.com:80
。如果网络浏览器向nc
发出请求,则该请求将发送给Google,但不会将响应发送到网络浏览器。这是因为管道是单向的。这可以使用命名管道来重定向输入和输出。mkfifo backpipe nc -l 12345 0<backpipe | nc www.google.com 80 1>backpipe
答案 1 :(得分:29)
打开两个不同的贝壳,并将它们并排放置。在两者中,转到/tmp/
目录:
cd /tmp/
在第一种类型中:
mkfifo myPipe
echo "IPC_example_between_two_shells">myPipe
在第二个中,输入:
while read line; do echo "What has been passed through the pipe is ${line}"; done<myPipe
在第二个shell中执行代码的第二部分之前,第一个shell不会给你任何提示。这是因为fifo读写是阻塞的。
您还可以通过执行ls -al myPipe
查看FIFO类型,并查看此特定类型文件的详细信息。
下一步是将代码放入脚本中!
答案 2 :(得分:27)
以下是命令:
$ mkfifo named_pipe
$ echo "Hi" > named_pipe &
$ cat named_pipe
第一个命令创建管道。
第二个命令写入管道(阻塞)。 &
将此放入后台,以便您可以继续在同一个shell中键入命令。当下一个命令清空FIFO时,它将退出。
最后一个命令从管道中读取。
答案 3 :(得分:2)
端子1:
$ mknod new_named_pipe p
$ echo 123 > new_named_pipe
端子2:
$ cat new_named_pipe
$ 123
$
new_named_pipe
的接收端和写入端都在那儿,因此它会显示信息并阻止阻塞命名管道在Linux中随处可见,我们在ls -l
命令中看到的大多数char和block文件都是char和block管道(所有这些都位于/ dev)。
这些管道可以是阻塞的也可以是非阻塞的,其主要优点是它们为IPC提供了最简单的方法。
答案 4 :(得分:0)
$ mkfifo pipe_name
在类 Unix 上,命名管道 (FIFO) 是一种特殊类型的文件,没有内容。 mkfifo
命令在文件系统上创建管道(为其分配名称),但不打开它。您需要像任何其他文件一样单独打开和关闭它。
当您需要从/向多个进程进行管道传输,或者您无法使用匿名管道连接两个进程时,命名管道非常有用。它们可以以多种方式使用:
与另一个进程并行:
$ echo 'Hello pipe!' > pipe_name & # runs writer in a background
$ cat pipe_name
Hello pipe!
这里的 writer 沿着 reader 运行,允许进程之间的实时通信。
Sequentially with file descriptors:
$ # open the pipe on auxiliary FD #5 in both ways (otherwise it will block),
$ # then open descriptors for writing and reading and close the auxiliary FD
$ exec 5<>pipe_name 3>pipe_name 4<pipe_name 5>&-
$
$ echo 'Hello pipe!' >&3 # write into the pipe through FD #3
...
$ exec 3>&- # close the FD when you're done
$ # (otherwise reading will block)
$ cat <&4
Hello pipe!
...
$ exec 4<&-
事实上,通过管道的通信可以是顺序的,但它是limited to a buffer size of 64 KB。
最好使用描述符来传输多条数据,以减少开销。
有条件地with signals:
$ handler() {
> cat <&3
>
> exec 3<&-
> trap - USR1 # unregister signal handler (see below)
> unset -f handler writer # undefine the functions
> }
$
$ exec 4<>pipe_name 3<pipe_name 4>&-
$ trap handler USR1 # register handler for signal USR1
$
$ writer() {
> if <condition>; then
> kill -USR1 $PPID # send the signal USR1 to a specified process
> echo 'Hello pipe!' > pipe_name
> fi
> }
$ export -f writer # pass the function to child shells
$
$ bash -c writer & # can actually be run sequentially as well
$
Hello pipe!
FD 允许在 shell 准备好接收数据之前开始数据传输。顺序使用时需要。
如果管道缓冲区填满,应在数据之前发送信号以防止死锁。
当管道的所有描述符都关闭时,管道本身(及其内容)将被销毁。剩下的只是一个名字。
要使管道在给定名称下匿名且不可用(可以在管道仍然打开时完成),您可以使用 rm
控制台命令(这与 mkfifo
命令相反):
$ rm pipe_name