为什么进程在 fifo 读取之前(似乎)不存在

为什么进程在 fifo 读取之前(似乎)不存在

我有一个简单的 Python 脚本:

#!/usr/bin/python

import os, sys

sys.stderr.write('I am %s' % os.getpid())
sys.stderr.flush()

print "hello"

sys.stderr.write('I am done')

当我从 Bash 运行此脚本并将标准输出重定向到 FIFO 时:

$ mkfifo fifo
$ /pyscript > fifo

奇怪的是,在我从 FIFO 读取之前:

  • 我不会收到“我是(PID)”消息,

  • 我看不到使用的脚本ps -ef

  • 并使用拉索夫,我看不到有人拥有先进先出文件打开!

一旦我从 FIFO 中读取数据,我正在写入 stderr 的两条消息就会立即出现。

怎么了?


背景:我正在编写一个测试,在其中创建 FIFO 并向其写入“hello”;然后我运行测试并期望 SUT不是从中读取; IE。忽略该文件即可。我尝试这样做,mkfifo test_fifo; /bin/echo hello > test_fifo &; run_the_test; killall echo但令我惊讶的是,这个echo过程从未存在过!在这样的测试之后我应该如何“清理”(除了rm test_fifo)......?

答案1

在成功完成任何文件重定向之前,shell 不会运行程序。该命令pyscript > fifo将导致 shell 分叉,然后尝试打开fifo.仅当某些进程已打开fifo以供读取时,此操作才会成功。在此之前,子 shell 将处于管道等待状态。

$ (sleep 10;ps -l -t pts/0)&
[1] 2574
$ pyscript > fifo
F S   UID    PID   PPID WCHAN  TTY    CMD
0 S  1000   2554   2535 wait   pts/0  bash  //interactive shell
1 S  1000   2574   2554 wait   pts/0  bash  //fork of shell, parent of sleep and ps
1 S  1000   2576   2554 pipe_w pts/0  bash  //fork of shell, waiting to open fifo
0 R  1000   2577   2574 -      pts/0  ps

答案2

管道或 FIFO 的两端必须同时打开。如果您从没有任何进程写入的管道或 FIFO 文件中读取数据(可能是因为它们都已关闭文件或退出),则读取将返回文件结尾。写入没有读取过程的管道或 FIFO 将被视为错误条件;它会生成 SIGPIPE 信号,如果该信号被处理或阻止,则会失败并显示错误代码 EPIPE。

http://www.gnu.org/software/libc/manual/html_node/Pipes-and-FIFOs.html

相关内容