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

Alo*_*dal 5 shell process io-redirection 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')
Run Code Online (Sandbox Code Playgroud)

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

$ mkfifo fifo
$ /pyscript > fifo
Run Code Online (Sandbox Code Playgroud)

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

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

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

  • 并使用lsof,我看不到任何人打开了fifo文件!

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

怎么了?


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

Mar*_*ick 5

在成功完成任何文件重定向之前,shell 不会运行程序。该命令pyscript > fifo将导致 shell fork 然后尝试打开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
Run Code Online (Sandbox Code Playgroud)


Vin*_*inz 4

\n

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

\n
\n\n

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

\n