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

发布于 2024-10-01 02:55:24 字数 45 浏览 7 评论 0原文

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

Can someone post a simple example of using named pipes in Bash on Linux?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

清醇 2024-10-08 02:55:24

命名管道实际使用的最佳示例之一...

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

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

<前><代码>nc -l 12345 |数控 www.google.com 80

端口 12345 代表请求。

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

mkfifo 后管
nc -l 12345 0<后管 | nc www.google.com 80 1> 后管

One of the best examples of a practical use of a named pipe...

From http://en.wikipedia.org/wiki/Netcat:

Another useful behavior is using netcat as a proxy. Both ports and hosts can be redirected. Look at this example:

nc -l 12345 | nc www.google.com 80

Port 12345 represents the request.

This starts a nc server on port 12345 and all the connections get redirected to google.com:80. If a web browser makes a request to nc, the request will be sent to google but the response will not be sent to the web browser. That is because pipes are unidirectional. This can be worked around with a named pipe to redirect the input and output.

mkfifo backpipe
nc -l 12345  0<backpipe | nc www.google.com 80 1>backpipe
百变从容 2024-10-08 02:55:24

以下是命令:

mkfifo named_pipe
echo "Hi" > named_pipe &
cat named_pipe

第一个命令创建管道。

第二个命令写入管道(阻塞)。 & 将其置于后台,以便您可以继续在同一 shell 中键入命令。当下一个命令清空 FIFO 时,它将退出。

最后一个命令从管道读取。

Here are the commands:

mkfifo named_pipe
echo "Hi" > named_pipe &
cat named_pipe

The first command creates the pipe.

The second command writes to the pipe (blocking). The & puts this into the background so you can continue to type commands in the same shell. It will exit when the FIFO is emptied by the next command.

The last command reads from the pipe.

彡翼 2024-10-08 02:55:24

打开两个不同的贝壳,并将它们并排放置。在这两个目录中,都转到 /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 不会给您任何提示在第二个外壳中。这是因为fifo读写是阻塞的。

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

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

Open two different shells, and leave them side by side. In both, go to the /tmp/ directory:

cd /tmp/

In the first one type:

mkfifo myPipe
echo "IPC_example_between_two_shells">myPipe

In the second one, type:

while read line; do echo "What has been passed through the pipe is ${line}"; done<myPipe

First shell won't give you any prompt back until you execute the second part of the code in the second shell. It's because the fifo read and write is blocking.

You can also have a look at the FIFO type by doing a ls -al myPipe and see the details of this specific type of file.

Next step would be to embark the code in a script!

念三年u 2024-10-08 02:55:24

创建命名管道

$ mkfifo pipe_name

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

使用命名管道

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

  • 与另一个进程并行:

    $ echo '你好管道!' >管道名称 & # 在后台运行 writer
    $ cat 管道名称
    你好管子!
    

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

  • 按文件描述符顺序

    $ # 以两种方式打开辅助 FD #5 上的管道(否则会阻塞),
    $#然后打开描述符进行读写并关闭辅助FD
    $ exec 5<>管道名称 3>管道名称 4<管道名称 5>&-
    $
    $ echo '你好管道!' >&3 # 通过 FD #3 写入管道
      ...
    $ exec 3>&- # 完成后关闭 FD
    $#(否则读取会阻塞)
    $猫<&4
    你好管子!
    ...
    $执行4<&-
    

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

  • 有条件地带有信号

    $ 处理程序() {
    >猫<&3
    >
    >执行3<&-
    > trap - USR1 # 注销信号处理程序(见下文)
    > unset -f handler writer # 取消定义函数
    > }
    $
    $ exec 4<>管道名称 3<管道名称 4>&-
    $ trap handler USR1 # 注册信号 USR1 的处理程序
    $
    $ 作家() {
    > if <条件>;然后
    > Kill -USR1 $PPID # 发送信号 USR1 到指定进程
    > echo '你好管道!' >管道名称
    >菲
    > }
    $ export -f writer # 将函数传递给子 shell
    $
    $ bash -c writer & # 实际上也可以顺序运行
    $
    你好管子!
    

    FD 允许在 shell 准备好接收数据之前开始数据传输。顺序使用时必需。
    该信号应在数据之前发送,以防止管道缓冲区填满时发生死锁。

销毁命名管道

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

$ rm pipe_name

Creating a named pipe

$ mkfifo pipe_name

On Unix-likes named pipe (FIFO) is a special type of file with no content. The mkfifo command creates the pipe on a file system (assigns a name to it), but doesn't open it. You need to open and close it separately like any other file.

Using a named pipe

Named pipes are useful when you need to pipe from/to multiple processes or if you can't connect two processes with an anonymous pipe. They can be used in multiple ways:

  • In parallel with another process:

    $ echo 'Hello pipe!' > pipe_name &       # runs writer in a background
    $ cat pipe_name
    Hello pipe!
    

    Here writer runs along the reader allowing real-time communication between processes.

  • 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<&-
    

    In fact, communication through a pipe can be sequential, but it's limited to 64 KB (buffer size).
    It's preferable to use descriptors to transfer multiple blocks of data in order to reduce overhead.

  • Conditionally 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 allows data transfer to start before the shell is ready to receive it. Required when used sequentially.
    The signal should be sent before data to prevent a deadlock if pipe buffer will fill up.

Destroying a named pipe

The pipe itself (and its content) gets destroyed when all descriptors to it are closed. What's left is just a name.
To make the pipe anonymous and unavailable under the given name (can be done when the pipe is still open) you could use the rm con­sole com­mand (it's the opposite of mkfifo command):

$ rm pipe_name
一刻暧昧 2024-10-08 02:55:24

终端 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 文件/code> 命令是 char 和 block 管道(所有这些都位于 /dev)。
这些管道可以是阻塞的和非阻塞的,主要优点是它们为IPC提供了最简单的方法。

Terminal 1:

$ mknod new_named_pipe p
$ echo 123 > new_named_pipe
  • Terminal 1 created a named pipe.
  • It wrote data in it using echo.
  • It is blocked as there is no receiving end (as pipes both named and unnamed need receiving and writing ends to it)

Terminal 2:

$ cat new_named_pipe
$ 123
$ 
  • From Terminal 2, a receiving end for the data is added.
  • It read the data in it using cat.
  • Since both receiving and writing ends are there for the new_named_pipe it displays the information and blocking stops

Named pipes are used everywhere in Linux, most of the char and block files we see during ls -l command are char and block pipes (All of these reside at /dev).
These pipes can be blocking and non-blocking, and the main advantage is these provides the simplest way for IPC.

静若繁花 2024-10-08 02:55:24

我想说的是,您可以为管道操作创建后台进程,而不是主cmd。它将对您进行自定义日志处理有很大帮助。

让我们有以下多行命令。

make target1 \
  --opt 1 \
  --opt 2

我们需要即时从 make 中 grep 一些东西。很难将 multine 命令替换为 ${cmd} >log & (手动或使用 sed 等工具),因此可以将其替换为 >log ${cmd}< /code> 相反:

mkfifo log
grep "something" log &
>log make target1 \
  --opt 1 \
  --opt 2

谢谢。

I want to say that you can create background process for pipe operation instead of main cmd. It will help you a lot with custom log processing.

Let we have the following multiline command.

make target1 \
  --opt 1 \
  --opt 2

We need to grep something from make on the fly. It is hard to replace multine command with ${cmd} >log & (manually or using tools like sed), so you can replace it with >log ${cmd} instead:

mkfifo log
grep "something" log &
>log make target1 \
  --opt 1 \
  --opt 2

Thank you.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文