unix - 防止 FIFO 关闭/重用关闭的 FIFO

标签 unix named-pipes eof fifo

考虑以下场景:

名为 test 的 FIFO被 build 。在一个终端窗口 (A) 中,我运行 cat <test在另一个 (B) cat >test 。现在可以在窗口 B 中写入并在窗口 A 中获取输出。也可以终止进程 A 并重新启动它,并且仍然能够按照怀疑使用此设置。但是,如果您终止窗口 B 中的进程,B 将(据我所知)通过 FIFO 发送 EOF 来处理 A 并终止它。

事实上,如果您运行的进程不在 EOF 处终止,您仍然无法使用重定向到该进程的 FIFO。我认为这是因为这个 FIFO 被认为是关闭的。

有办法解决这个问题吗?

我遇到这个问题的原因是因为我想向在屏幕 session 中运行的我的世界服务器发送命令。例如:echo "command" >FIFO_to_server 。这可能可以通过单独使用屏幕来完成,但我对屏幕不太满意,我认为仅使用管道的解决方案会更简单、更干净。

最佳答案

A 正在读取文件。当到达文件末尾时,它将停止读取。这是正常行为,即使文件恰好是 fifo。您现在有四种方法。

  1. 更改阅读器的代码,使其在文件结束后继续阅读。这就是说输入文件是无限的,到达文件末尾只是一种幻觉。对您来说不实用,因为您必须更改 Minecraft 服务器代码。
  2. 应用 Unix 哲学。你有一个作者和一个读者,他们在协议(protocol)上不一致,所以你插入了一个工具来连接他们。恰好,unix 工具箱中有这样一个工具:tail -ftail -f 即使在看到文件末尾后也会继续从输入文件中读取内容。让所有客户端与管道通信,并将 tail -f 连接到 minecraft 服务器:

    tail -n +1 -f client_pipe | minecraft_server &
    
  3. As mentioned by jilles ,使用一个技巧:管道支持多个写入器,并且只有当最后一个写入器消失时才会关闭。因此,请确保有一个永远不会消失的客户。

    while true; do sleep 999999999; done >client_pipe &
    
  4. 问题在于服务器从根本上来说是为处理单个客户端而设计的。要处理多个客户端,您应该更改为使用套接字。将套接字视为“元管道”:连接到套接字会创建一个管道,一旦客户端断开连接,该特定管道就会关闭,但服务器可以接受更多连接。这是一种干净的方法,因为它还可以确保如果两个客户端碰巧同时连接(使用管道,它们的命令可以散布),您不会混淆数据。但是,它需要更改我的世界服务器。

关于unix - 防止 FIFO 关闭/重用关闭的 FIFO,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5957386/

相关文章:

linux - 删除shell脚本中以特定字符串开头的目录

c - 如何避免在命名管道关闭后阻塞 read()

cocoa - 通过 NSPipe 或 NSFileHandle 发送 EOF 到 NSTask

C在while循环中读取输入

python - 用户安装的 python 模块

debugging - 使用set命令在Unix中禁用详细调试

创建一个进程并告诉它 sleep ?

c# - 单元测试命名管道

sql - 命名管道提供程序无法打开与 SQL Server 1231 的连接

c - 使用 fgets 达到 EOF