Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

What I am trying to do is run python in a terminal window and redirect it's stdin from a named pipe. Then I write to the named pipe in another terminal and have that command execute on python.

Terminal 1:

mkfifo p1
python < p1

Terminal 2:

echo -n "print \"Hello World\"" > p1

What happens is - python prints Hello World and exits. What I want to do is keep python running to take a next command. How do I do this in the shell?

share|improve this question
add comment

4 Answers

up vote 5 down vote accepted

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:
exec 3>&1
share|improve this answer
    
Thanks! It worked. I am not familiar with what you have done. Would you please add some details to your answer to explain what is going on. What is exec 3> p1 doing and what is &3 & exec 3> &1? Thank you. –  Lord Loh. Apr 19 '13 at 18:15
    
Your answer reminded me of this banner - sphotos-b.xx.fbcdn.net/hphotos-ash4/… it is the cover pic of a friend on facebook :-) –  Lord Loh. Apr 19 '13 at 18:18
add comment

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.

share|improve this answer
add comment

Maybe the tail approach is better (more flexible) but as an alternative:

{ echo -n "print \"Hello World\""; cat; } > p1
share|improve this answer
    
This does not work as I want. -n might have o be removed. And after that, 0. The terminal with the echo command gets blocked 1. python does not execute the command till I press ^c in the echo terminal and both process terminate. –  Lord Loh. Apr 19 '13 at 3:23
1  
@LordLoh. May be a buffering problem. Probably python will execute the command if enough output has been created so that the first line finally gets written to the FIFO. But as there is a working solution it wouldn't make sense to put effort in solving this problem. –  Hauke Laging Apr 19 '13 at 3:51
add comment

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.

share|improve this answer
    
I tried echo "print \"Hello World\" " > p1 in the second terminal and nothing happened - but the terminal was not blocked either. The terminal with python remained blocked till I ^c it and exit it and terminate python with a keyboard interrupt message being displayed by python. –  Lord Loh. Apr 19 '13 at 3:26
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.