Shell – Why process does not (seem to) exist before fifo read

fifoio-redirectionprocessshell

I have a trivial Python script:

#!/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')

When I run this script from Bash and redirect the stdout to FIFO:

$ mkfifo fifo
$ /pyscript > fifo

the strange thing is, that before I read from the FIFO:

  • I won't get the "I am (PID)" message,

  • I can't see the script using ps -ef

  • and using lsof, I can't see anybody has the fifo file open!

Once I do read from the FIFO, the both messages that I'm writing to stderr appear at once.

What is happening?


The background: I'm writing a test where I create FIFO and write 'hello' to it; then I run a test and expect the SUT to not read from it; ie. just ignore the file. I tried to do mkfifo test_fifo; /bin/echo hello > test_fifo &; run_the_test; killall echo but to my surprise, the echo process never exists! How should I "clean up" after such test (apart from rm test_fifo)…?

Best Answer

The shell will not run a program until any file redirections have been completed successfully. The command pyscript > fifo will cause the shell to fork and then try to open fifo. This will succeed only when some process has opened fifo for reading. Until then, the child shell will be in pipe wait.

$ (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
Related Question