【问题标题】:Bash pipe execution orderBash 管道执行顺序
【发布时间】:2021-06-05 05:42:27
【问题描述】:

如果我在 Terminal1 上打开一个 nc 监听

nc -l 35555

并以这种方式在Terminal2上进行连接

mkfifo /tmp/f
cat /tmp/f | nc 127.0.0.1 35555 > /tmp/f

现在我有几个问题

在 Terminal2 上,您可以看到正在等待的东西。那是什么?

  • 是cat进程还是nc进程?
  • 它们按什么顺序执行?

如果我在 Terminal1 上写一个字符串,那个字符串就会回来。

  • 为什么cat /tmp/f | nc 127.0.0.1 35555 > /tmp/f 不创建循环?

接收到的字符串从nc出来,进入/tmp/f。由于 cat 字符串开始输入 nc,发送回 Terminal1 并在 /tmp/f 等中再次发送。

  • 为什么 fifo 的猫不是阻塞操作?从技术上讲它并没有结束,那么为什么要执行 nc?

谢谢。

【问题讨论】:

    标签: linux bash operating-system pipe


    【解决方案1】:
    • 是cat进程还是nc进程?

    两者兼而有之。 cat 正在等待将某些内容写入 FIFO。 nc 正在等待将某些内容写入其stdin 或通过网络套接字接收某些内容。

    • 它们按什么顺序执行?

    管道中的所有命令同时运行。

    • 为什么cat /tmp/f | nc 127.0.0.1 35555 > /tmp/f 不创建循环?

    第一个终端没有发回它从网络接收到的内容,它只是将它打印到终端。当您在终端 1 上键入内容时,它会被写入网络一次。终端 2 上的 nc 将其写入 /tmp/f。然后它读取它并将其发送到网络。终端 1 上的 nc 读取并打印它。就这样结束了。

    -为什么fifo的猫不是阻塞操作?从技术上讲它并没有结束,那么为什么要执行 nc 呢?

    管道中的命令不会等待前一个命令退出。这样就不可能写出这样的代码了

    tail -f filename | grep word
    

    因为tail -f 永远不会退出(直到你用Ctl-c 杀死它,但这也会杀死grep)。所有进程都运行,这允许后面的程序处理早期程序的部分输出。

    所以nc 不会等待cat 退出。它同时运行,并且可能使用select()epoll() 同时监听来自stdin 和网络套接字的输入(它也可能为每个使用单独的线程)。所以当cat在FIFO上阻塞时,它可以从终端1读取网络数据,然后将其写入FIFO。

    【讨论】:

    • 谢谢。一个非常完整的答案
    猜你喜欢
    • 1970-01-01
    • 2016-02-01
    • 2023-02-03
    • 2016-04-21
    • 2019-01-30
    • 2022-08-02
    • 1970-01-01
    • 1970-01-01
    • 2014-02-07
    相关资源
    最近更新 更多