Why does the read command not take interactive options when run by sh?

When you pipe the output of curl into sh you're making the script text be standard input of the shell, which takes it in as commands to run. After that, there's nothing left to read. Even if it were to try, it wouldn't get anything from the terminal input, because it's not connected to it. The pipe has replaced standard input for the sh process.

The next problem is that read -i is not a POSIX sh feature, but rather an extension supported by bash. Ubuntu uses dash, a minimal POSIX-compliant shell with minimal extensions, as /bin/sh by default. That's why it rejects the -i option specifically (although it does support -p).

If you're using a more capable shell yourself, you can try something like:

bash <(curl http://example.com/provisioning.sh)

which creates a pipe for bash to read the output of curl from and provides it as the script file argument. In this case, the standard input of the script is still connected to the terminal, and read will work (but note the big caveat below the line).


I'll note also that "curl | sh" is generally frowned upon as an obvious security problem, but you know best the situation your script is in.