Output appearing where terminal input should may indicate forgetting to close a pipe

This is part of the Semicolon&Sons Code Diary - consisting of lessons learned on the job. You're in the unix category.

Last Updated: 2024-04-18

Image I had the following code for executing PHP from Ruby via a pipe:

# Note:
# 1. The syntax for opening a pipe: "|command"
# 2. The fact that this is a write-only pipe ("w"). We are using this because a
# read-write pipe ("r+") (in Ruby at least) would hang at read until the input side is closed
php = open("|php", "w")
php.write <<EOF
One plus one is: <?php print 1 + 1; ?>
EOF

When this is run, something odd happens:

$ ruby php_running.rb

# i.e. It shows the output on the part of the terminal where you are supposed to type commands!
$ One plus one is 2

Why? Because we omitted any call to close the input end of the pipe, the operating system had to close it for us after the process finished. Which, in this case, caused the PHP output to be belatedly flushed after the next command prompt (symbolized by the $ symbol above) had already been printed.

The fix is usually at_exit handlers and the like to close pipes.

at_exit { php.close }

Resources

Lesson

Pipes you open really must be closed by your program.