我有几个 C 程序通过 Unix 中的 FIFO 命名管道来回发送消息,我想使用外部程序查看管道中发生了什么。问题是,如果我使用cat
,它会在下次程序调用write()
并关闭管道后停止,从而破坏程序之间的通信......然后就会发生不好的事情。我不明白为什么cat
要关闭我的管道。编辑:实际上,我今天做了完全相同的事情,它没有关闭管道,而是使进程停止从中读取。
那么有没有类似的东西,cat
除了它根本不会干扰管道,只打印它看到的任何东西?
如果相关的话,我在 C 中创建如下管道:
outs[i2/2] = open("/tmp/pipe_w", O_WRONLY);
ins[i2/2] = open("/tmp/pipe_r", O_RDONLY);
更新:这是一个终端示例。
我的进程在打开管道时打印此输出:
Opened in pipe at /tmp/ai1In
Opened out pipe at /tmp/ai1Out
然后我在一个单独的 shell 中执行此操作:
admin$ cat /tmp/ai1Out
ai1
它看到消息“ai1”通过,然后什么也没有。读取该管道的进程最终会永远等待。我杀死了cat
,但管道最终仍然没有被读取。
更新2:
cat [path] | tee [path]
在某些情况下有效。它不会明显干扰我的ai1Out
管道,但会干扰ai1In
.差异一定是由于我的代码造成的。无论如何,这意味着运行此命令会对使用管道的其他进程产生一些影响,这是我不希望的。当我尝试读取时ai1Out
,我只是看到了这一点,然后写入该管道的进程在下次调用时出现错误write()
:
admin$ cat /tmp/ai1In | tee /tmp/ai1In
]2,15,43,66,65,61,53,20,30,27,40,16,50,41,48[[[[[[[[
答案1
管道的定义是写入其中的数据在另一端读取。管道不会复制数据。在管道上读取是一种破坏性操作。如果管道上有两个读取器,则每个字节将仅由其中一个读取器读取。
如果你想通过管道监视两个程序之间的通信,你可以通过插入tee
之间的程序。然后有两条管道:一根从作者到读者,tee
一根从tee
作者到读者。
mkfifo pipe_w pipe_r
writer >pipe_w
reader <pipe_r
<pipe_w tee pipe_r
您问题中的管道命名方案不一致,所以我不知道您到底尝试了什么。看来您试图将数据从管道反馈回自身。这是行不通的:您创建了一个闭环,其中一些数据永远返回到管道中(只有部分数据,因为无法预测哪些字节将返回管道以及哪些字节将返回原始管道)读者)。
如果两个进程之间有一个管道,并且您无法更改管道,则监视它的最简单方法是跟踪写入器或读取器进程。例如,如果写入进程的 PID 为 123 并且在文件描述符 4 上打开管道,在 Linux 下,您可以使用
strace -p123 -e write=4