0

I wrote a shell script using bash built-in command select to create selection menu. It works well when invoking by bash directly. But if I use pipe | such as cat script.sh | bash, the select function will not work.

For example, code snippet shows

#!/usr/bin/env bash

arr=("Red Hat" "SUSE" "Debian")
PS3="Choose distribution:"

result=${result:-}

select item in "${arr[@]}"; do
    result="${item}"
    [[ -n "${result}" ]] && break    
done

echo "Result is ${result}"
unset PS3

Directly using bash script.sh, works well.

$ bash /tmp/test.sh 
1) Red Hat
2) SUSE
3) Debian
Choose distribution:1
Result is Red Hat

Using pipe |, it will output

$ cat /tmp/test.sh | bash
1) Red Hat
2) SUSE
3) Debian
Choose distribution:1) Red Hat
2) SUSE
3) Debian
Choose distribution:Choose distribution:Choose distribution:

This makes the script not work.

I don't know why? Does select do not suppoer pipe | or anything else?

1
  • You've created a situation where your script is trying to read from itself, since it inherits its standard input from the bash process that runs it. Don't run an interactive script like this. Commented Sep 25, 2017 at 11:45

1 Answer 1

2

select reads from stdin. stdin is coming from the pipe. If you want to get data from the tty, you can try:

#!/usr/bin/env bash

arr=("Red Hat" "SUSE" "Debian")
PS3="Choose distribution:"

result=${result:-}

select item in "${arr[@]}"; do
    result="${item}"
    [[ -n "${result}" ]] && break    
done < /dev/tty                      #  <------------------

echo "Result is ${result}"
unset PS3
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.