0

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?

    1 Answer 1

    1

    You've "used up" all of stdin by the time the select is executed, so it returns with status 1 and nothing selected

    Perhaps you were wanting to force interactivity by reading from /dev/tty?

    #!/usr/bin/env bash if [ ! -t 0 ]; then while IFS= read -r foo; do bar+=("$foo") done 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 </dev/tty 
    6
    • Thanks, this seems to work when stdin is piped but seems to break when there is no STDIN
      – jesse_b
      CommentedOct 5, 2023 at 19:06
    • It breaks in what way?CommentedOct 5, 2023 at 19:16
    • It never brings up the select list, it just sits there waiting for me to input stdin.
      – jesse_b
      CommentedOct 5, 2023 at 19:17
    • I don't see that in my testingCommentedOct 5, 2023 at 19:18
    • 1
      Suggest you change the -p /dev/stdin too so it works with file redirection as well as pipesCommentedOct 5, 2023 at 19:31

    You must log in to answer this question.

    Start asking to get answers

    Find the answer to your question by asking.

    Ask question

    Explore related questions

    See similar questions with these tags.