Skip to main content
added 544 characters in body; edited title
Source Link
jesse_b
  • 41.6k
  • 14
  • 108
  • 162

STDIN breaks my Why does a Bash script with select listexit without input when reading from stdin?

I haveI'm working on a Bash script that can optionally take someaccepts input on STDINfrom stdin and laterthen presents the user with a fewselection menu using select lists. When data is input on STDINThe issue arises when the script is provided data via stdin—the select list presentsmenu displays but exits immediately without takingaccepting any input, however it. It works fine when nothingno stdin data is provided via stdin.

I haveHere is a simpleminimal 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

Executing withoutExecution Without stdin The script works as expected:

$ ./script.sh
1) foo
2) bar
3) baz
#? 2
You have selected bar

Executing withExecution 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
#?
$

Does anyone know why this happensAs 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 to prevent itcan I fix this so the select menu works regardless of whether stdin is used?

STDIN breaks my select list

I have a script that can optionally take some input on STDIN and later presents the user with a few select lists. When data is input on STDIN the select list presents but exits without taking input, however it works fine when nothing is provided via stdin.

I have a simple 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

Executing without stdin:

$ ./script.sh
1) foo
2) bar
3) baz
#? 2
You have selected bar

Executing with stdin:

$ printf '%s\n' foo bar | ./script.sh
foo
bar
1) foo
2) bar
3) baz
#?
$

Does anyone know why this happens and how to prevent it?

Why does a Bash script with select exit without input when reading from stdin?

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?

Source Link
jesse_b
  • 41.6k
  • 14
  • 108
  • 162

STDIN breaks my select list

I have a script that can optionally take some input on STDIN and later presents the user with a few select lists. When data is input on STDIN the select list presents but exits without taking input, however it works fine when nothing is provided via stdin.

I have a simple 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

Executing without stdin:

$ ./script.sh
1) foo
2) bar
3) baz
#? 2
You have selected bar

Executing with stdin:

$ printf '%s\n' foo bar | ./script.sh
foo
bar
1) foo
2) bar
3) baz
#?
$

Does anyone know why this happens and how to prevent it?