How to read user input from a pipe?

As others have said, this is because the stdin of sh has been redirected to read from the pipe, it is not connected to the terminal as it would normally be. One thing you can do to get around this is to use /dev/tty to force the script to read from the terminal. Eg:

#!/bin/sh

read -p "Are you sure [Y/n]?" line </dev/tty
case "$line" in
  y|Y) echo "confirmed"
    ;;
  *) echo "not confirmed"
    ;;
esac

Normally you would only do this if you specifically want to prevent people from scripting the input, eg:

echo Y | sh confirmation.sh

This would still read from the terminal even though the user might expect this to automatically input Y at the prompt. It is common for programs that expect a password to do this.


sh 3<<CONFIRM /dev/fd/3
    $(cat ./confirmation.sh)
CONFIRM

sh 3<./confirmation.sh /dev/fd/3

note: thanks to @Graeme for correcting me on the above two examples...

Its a lot easier to do if you keep stdin clear.

2<./confirmation.sh . /dev/stderr

Or, since a terminal's 0 1 2 are all the same file, just add:

read line <&2

And your

cat ./confirmation.sh | sh

Works just fine.