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)...?
在成功完成任何文件重定向之前,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)
\n\n\n管道或 FIFO 的两端必须同时打开。如果您从没有任何进程写入的管道或 FIFO 文件中读取数据(可能是因为它们都已关闭文件或退出),则读取将返回文件结束符。写入没有读取进程的管道或 FIFO 将被视为错误条件;它会生成 SIGPIPE 信号,如果该信号被处理或阻止,则会失败并显示错误代码 EPIPE。
\n
http://www.gnu.org/software/libc/manual/html_node/Pipes-and-FIFOs.html
\n