Reputation: 4808
I have two scripts:
install.sh
#!/usr/bin/env bash
./internal_install.sh
internal_install.sh
#!/usr/bin/env bash
set -x
while true; do
read -p "Hello, what's your name? " name
echo $name
done
When I run ./install.sh
, all works as expected:
> ./install.sh
+ true
+ read -p 'Hello, what'\''s your name? ' name
Hello, what's your name? Martin
+ echo Martin
Martin
...
However, when I run with cat ./install.sh | bash
, the read
function does not block:
cat ./install.sh | bash
+ true
+ read -p 'Hello, what'\''s your name? ' name
+ echo
+ true
+ read -p 'Hello, what'\''s your name? ' name
+ echo
...
This is just a simplified version of using curl
which results in the same issue:
curl -sl https://www.conteso.com/install.sh | bash
How can I use curl
/cat
to have blocking read
in the internal script?
Upvotes: 2
Views: 1449
Reputation: 780673
read
reads from standard input by default. When you use the pipe, standard input is the pipe, not the terminal.
If you want to always read from the terminal, redirect the read
input to /dev/tty
.
#!/usr/bin/env bash
set -x
while true; do
read -p "Hello, what's your name? " name </dev/tty
echo $name
done
But you could instead solve the problem by giving the script as an argument to bash
instead of piping.
bash ./install.sh
When using curl
to get the script, you can use process substitution:
bash <(curl -sl https://www.conteso.com/install.sh)
Upvotes: 6