I am currently playing around with bash and did some scripting in the last days. I thought, that I’m done, but after some tests, it seems, that when it comes to a simple yes/no question that requires user interaction, it loops. The strange thing is, that it does not loop, whenever I run the script. It depends on how I run it. So here’s an example script:
#!/usr/bin/env bash
while true; do
read -rp " test? (y/n): " yn
case $yn in
[Yy]*)
FOO="y"
break
;;
[Nn]*)
FOO="n"
break
;;
*)
echo -e " Please answer yes or no."
echo ""
;;
esac
done
echo "You picked $FOO"
As you can see, it doesn’t do anything special. It asks for yes or no and displays a message if you type anything else. If I run it (on a Debian/Ubuntu machine) like this:
bash foo.sh
or like this:
chmod 755 foo.sh && ./foo.sh
or even like this (same script, hosted on GitHub Gist):
bash <(wget -qO- git.io/JUGDp)
it works as expected. But if I run it like this, it loops:
wget -qO- git.io/JUGDp | bash
I have a basic idea of why this happens, but even if my assumptions are correct, how can I prevent it?
2
Answers
When you run Bash at the end of a pipeline, its standard input is connected to the pipe; therefore
read
will not be able to read from the terminal.Append
</dev/tty
to yourread
command to force reading fromtty
and not fromstdin
.