在Linux Bash中使用命名管道的示例

时间:2010-11-06 16:30:35

标签: linux bash pipe

有人可以在Linux中发布一个在Bash中使用命名管道的简单示例吗?

5 个答案:

答案 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
  • 端子1创建了一个命名管道。
  • 它使用echo将数据写入其中。
  • 由于没有接收端,因此被阻塞(因为命名和未命名的管道都需要接收和写入端)

端子2:

$ cat new_named_pipe
$ 123
$ 
  • 从2号航站楼添加了数据接收端。
  • 它使用cat读取其中的数据。
  • 由于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