I'm working on a Bash script that optionally accepts input from stdin and then presents the user with a selection menu using select. The issue arises when the script is provided data via stdin—the select menu displays but exits immediately without accepting any input. It works fine when no stdin data is provided.
Here is a minimal example:
#!/usr/bin/env bash
if [[ -p /dev/stdin && ${#bar[@]} -eq 0 ]]; then
while IFS= read -r foo; do
bar+=("$foo")
done </dev/stdin
fi
for foo in "${bar[@]}"; do
echo "$foo"
done
select thing in foo bar baz; do
case $thing in
*) echo "You have selected $thing"; break;;
esac
done
Execution Without stdin The script works as expected:
$ ./script.sh
1) foo
2) bar
3) baz
#? 2
You have selected bar
Execution With stdin The issue occurs when data is piped into the script:
$ printf '%s\n' foo bar | ./script.sh
foo
bar
1) foo
2) bar
3) baz
#?
$
As shown, the script exits the select loop immediately after displaying the menu.
What I've Tried:
- Confirming the script's behavior when no stdin data is provided.
- Redirecting stdin in various ways (e.g., /dev/tty) with limited success.
Question
Why does the script's select menu exit immediately when stdin data is provided, and how can I fix this so the select menu works regardless of whether stdin is used?