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?