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

Dre*_*eur 51 linux bash pipe

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

Bri*_*nts 84

实用命名管道的最佳例子之一......

来自http://en.wikipedia.org/wiki/Netcat

另一个有用的行为是使用netcat作为代理.端口和主机都可以重定向.看看这个例子:

nc -l 12345 | nc www.google.com 80
Run Code Online (Sandbox Code Playgroud)

端口12345表示请求这将在端口12345上启动nc服务器,并且所有连接都将重定向到google.com:80.如果网络浏览器向nc发出请求,该请求将被发送到谷歌但响应将不会发送到网络浏览器.这是因为管道是单向的.这可以使用命名管道来重定向输入和输出.

mkfifo backpipe
nc -l 12345  0<backpipe | nc www.google.com 80 1>backpipe
Run Code Online (Sandbox Code Playgroud)

  • 虽然这是一个有用的例子,如果你正在构建这种性质的代理,你通常最好使用[socat](http://www.dest-unreach.org/socat/),这是一个Unix命令-line工具,实质上实现了一个_very_功能齐全的特定于域的语言,用于构建代理和(在更有限的程度上)服务器.使用`socat STDIO TCP:www.google.com:80`可以更加可靠和高效地完成这个特定的示例. (8认同)
  • @hft怎么样?mkfifo backpipe; nc -l 12345 0 <backpipe | nc www.google.com 80 1> backpipe`? (3认同)

小智 29

打开两个不同的壳,并将它们并排放置.在两者中,转到/tmp/目录:

cd /tmp/
Run Code Online (Sandbox Code Playgroud)

在第一种类型中:

mkfifo myPipe
echo "IPC_example_between_two_shells">myPipe
Run Code Online (Sandbox Code Playgroud)

在第二个中,键入:

while read line; do echo "What has been passed through the pipe is ${line}"; done<myPipe
Run Code Online (Sandbox Code Playgroud)

在第二个shell中执行代码的第二部分之前,第一个shell不会给你任何提示.这是因为fifo读写是阻塞的.

您还可以通过执行ls -al myPipe查看FIFO类型并查看此特定类型文件的详细信息.

下一步是将代码放入脚本中!

  • 是否可以对 fifo 进行非阻塞写入? (3认同)

Kha*_*led 28

以下是命令:

$ mkfifo named_pipe

$ echo "Hi" > named_pipe &

$ cat named_pipe
Run Code Online (Sandbox Code Playgroud)

第一个命令创建管道.

第二个命令写入管道(阻塞).该&放到这个背景,所以你可以继续在同一个shell键入的命令.当下一个命令清空FIFO时,它将退出.

最后一个命令从管道中读取.

  • 我会将#更改为$所以它不是全部注释(而不是以root身份运行!) (7认同)
  • 习惯上"#"引用根提示符(即根shell中的提示符).这里没有任何东西需要在root shell中运行. (3认同)
  • `echo` 将阻塞,因此如果在同一个 shell 中执行,它不会运行,除非第二行以结尾 `&amp;` 放在后台。 (2认同)

Evg*_*423 20

创建命名管道

\n
$ mkfifo pipe_name\n
Run Code Online (Sandbox Code Playgroud)\n

在类 Unix 上,命名管道 (FIFO) 是一种没有内容的特殊类型的文件。该mkfifo命令在文件\xc2\xa0系统上创建管道(为其分配名称),但不打开它。您需要像任何其他文件一样单独打开和关闭它。

\n

使用命名管道

\n

当您需要从/到多个进程进行管道传输或者无法使用匿名管道连接两个进程时,命名管道非常有用。它们可以通过多种方式使用:

\n
    \n
  • 与另一个进程并行:

    \n
    $ echo \'Hello pipe!\' > pipe_name &       # runs writer in a background\n$ cat pipe_name\nHello pipe!\n
    Run Code Online (Sandbox Code Playgroud)\n

    在这里,编写器与读取器一起运行,允许进程之间进行实时通信。

    \n
  • \n
  • 按顺序使用 file\xc2\xa0descriptors

    \n
    $ # open the pipe on auxiliary FD #5 in both ways (otherwise it will block),\n$ # then open descriptors for writing and reading and close the auxiliary FD\n$ exec 5<>pipe_name 3>pipe_name 4<pipe_name 5>&-\n$\n$ echo \'Hello pipe!\' >&3                 # write into the pipe through FD #3\n  ...\n$ exec 3>&-                              # close the FD when you\'re done\n$                                        # (otherwise reading will block)\n$ cat <&4\nHello pipe!\n...\n$ exec 4<&-\n
    Run Code Online (Sandbox Code Playgroud)\n

    事实上,通过管道的通信可以是顺序的,但它限制为 64\xc2\xa0KB(缓冲区大小)
    \n最好使用描述符以\xc2\xa0顺序\xc2\xa0传输多个数据块,以减少开销。

    \n
  • \n
  • 有条件地使用信号

    \n
    $ handler() {\n>     cat <&3\n>\n>     exec 3<&-\n>     trap - USR1                        # unregister signal handler (see below)\n>     unset -f handler writer            # undefine the functions\n> }\n$\n$ exec 4<>pipe_name 3<pipe_name 4>&-\n$ trap handler USR1                      # register handler for signal USR1\n$\n$ writer() {\n>     if <condition>; then\n>         kill -USR1 $PPID               # send the signal USR1 to a specified process\n>         echo \'Hello pipe!\' > pipe_name\n>     fi\n> }\n$ export -f writer                       # pass the function to child shells\n$\n$ bash -c writer &                       # can actually be run sequentially as well\n$\nHello pipe!\n
    Run Code Online (Sandbox Code Playgroud)\n

    FD 允许 data\xc2\xa0transfer 在 shell 准备好接收之前启动。顺序使用时需要。
    \n信号应在数据之前发送,以防止管道\xc2\xa0buffer 填满\xc2\xa0up 时出现死锁。

    \n
  • \n
\n

销毁命名管道

\n

当管道的所有描述符都关闭时,管道本身(及其内容)就会被销毁。剩下的只是一个名字。
\n要使管道匿名并且在给定名称下不可用(可以在管道仍然打开时完成),您可以使用rmcon\xc2\xadsole\xc2\xa0com\xc2\xadmand (它与命令相反mkfifo) :

\n
$ rm pipe_name\n
Run Code Online (Sandbox Code Playgroud)\n

  • 没有 _complete(-ish)_ 示例,所以我写了一个。 (2认同)