Getting stdin from a named pipe

You need to

  • Run python interactively even though its stdin is not a terminal: use python -i
  • keep the writing end of the pipe open, otherwise python will detect EOF and exit.

So:

python -i < p1

And elsewhere:

exec 3> p1
echo '1j*1j' >&3
...
# and when done, close that file descriptor so python sees the EOF:
exec 3>&-

You can use tail -f to keep the fifo open after echo writes to it.

tail -n1 -f p1 | python

Why this works

python is reading from p1. When it reaches the end of the file, it stops reading. This is normal behavior for file reads, even if the file is a named pipe. tail with the -f (follow) flag will keep reading from a file after its end is reached.


You need to send the entire program at once.

When you call run python < p1 the shell is waiting for input before invoking python. That is, python doesn't even begin executing at all until the entire data stream has been read by the shell and then is passed in its entirety to python.

Even running python -u p1 instead (that is, unbuffered and read from file p1) python will try to read the entire file before it executes any of it.

Try this experiment.

Terminal 1:

mkfifo p1
python < p1

Terminal 2:

cat > p1
print "Hello World"
print "Hello World"

You'll see that you can send multiple lines but python in Term 1 does nothing. Now press ctrl+D. The entire program executes at once.

So, to summarize, if you want python to read from a pipe you need to send the entire program. You can't use python interactively this way.