Skip to main content

Linux 重定向与管道

Linux 命名管道 FIFO

命名管道(FIFO,First In First Out)是 Linux 中一种特殊的文件类型,让不同进程之间可以通过“管道”传递数据。跟普通的管道(|)不同,命名管道是个实际存在于文件系统中的文件,可以让不相关的进程通信。

1. 什么是命名管道?

命名管道(FIFO)就像一个有名字的管道文件,存在于文件系统里,任何进程都可以通过它读写数据。普通管道(|)只能在有亲缘关系的进程(比如父子进程)或通过 stdout/stdin 连接的命令中使用,而命名管道允许任意进程通过文件路径访问它。

  • 特点:FIFO 是“先进先出”的,数据按写入顺序被读取。
  • 文件类型:在文件系统里,FIFO 文件的类型标记为 p(pipe)。

你可以用 ls -l 看到 FIFO 文件,比如:

ls -l myfifo

输出可能是:

prw-r--r-- 1 user user 0 Aug  9 20:00 myfifo

这里的 p 表示它是个命名管道。

2. 创建命名管道

可以用 mkfifo 命令创建命名管道。基本语法是:

mkfifo myfifo

这会在当前目录创建一个名叫 myfifo 的命名管道文件。

  • 检查创建结果
ls -l myfifo

会看到类型为 p 的文件。

也可以用 mknod 命令(稍微老派,但也常用):

mknod myfifo p
  • 参数说明p 指定创建的是管道文件。
  • 权限:FIFO 文件跟普通文件一样有权限设置,创建时可以用 chmod 修改:
mkfifo myfifo
chmod 666 myfifo

这让所有用户都能读写 myfifo

3. 向命名管道写入数据

命名管道可以像文件一样写入数据,但需要有进程在另一端读取,否则写入会阻塞(卡住)。可以用重定向或命令向 FIFO 写入。

比如,打开一个终端,写入数据:

echo "Hello, FIFO!" > myfifo

这行命令会把 "Hello, FIFO!" 写入 myfifo,但会卡住,直到有进程从 myfifo 读取数据。

可以用其他命令写入,比如:

cat file.txt > myfifo

这会把 file.txt 的内容写入 myfifo

4. 从命名管道读取数据

读取 FIFO 也像操作文件,用重定向或命令。打开另一个终端,读取数据:

cat < myfifo

运行后,终端会显示:

Hello, FIFO!

一旦数据被读取,写入端(echo)的阻塞会解除,两个进程就完成了通信。

可以用其他命令读取,比如:

grep "Hello" < myfifo

这会从 myfifo 读取数据,过滤包含 “Hello” 的行。

5. 命名管道的阻塞行为

FIFO 有一个重要特点:读写阻塞

  • 如果没有进程读取,写入会卡住。
  • 如果没有进程写入,读取会卡住。

这保证了数据传递的同步性。比如:

mkfifo myfifo
echo "Test data" > myfifo

运行后,echo 会卡住,直到你在另一个终端运行:

cat < myfifo

cat 读取数据后,echo 才会继续执行。

如果不想阻塞,可以用非阻塞模式(需要 open 系统调用,bash 里稍微复杂,常用工具如 cat 默认阻塞)。

6. 多进程通信

命名管道的强大之处在于让不相关的进程通信。比如,一个进程写日志,另一个进程实时处理:

终端 1(写入):

tail -f /var/log/syslog > myfifo

终端 2(读取并处理):

grep "error" < myfifo
  • tail -f 持续把系统日志写入 myfifo
  • grepmyfifo 读取并过滤出包含 “error” 的行。

这样就实现了一个简单的实时日志监控。

7. 删除命名管道

用完 FIFO 后,可以像删除普通文件一样用 rm 删掉:

rm myfifo

删除后,FIFO 文件消失,相关进程的读写会停止(可能报错,视情况而定)。

8. 实际例子:综合运用

来个综合例子,模拟两个进程通信:

终端 1(生产数据):

mkfifo myfifo
while true; do
    echo "Data at $(date)" >> myfifo
    sleep 1
done
  • 创建 myfifo
  • 循环每秒向 myfifo 写入当前时间。

终端 2(处理数据):

cat < myfifo | grep "2025"
  • myfifo 读取数据。
  • 过滤包含 “2025” 的行(假设是 2025 年)。

终端 2 会持续显示类似:

Data at Sat Aug  9 20:00:01 HKT 2025