Unable to accept user input in bash

Viewed 110
while
   echo "Do you want to continue y/n?"
   read install_to_default
   [[ -z $install_to_default || $install_to_default != [yYnN] ]]
do echo "The response is invalid. A valid response is y or n."; done

Running the above script as root causes no problems, but when I try to run the script as a different user with the below changes it causes an infinite loop.

sudo -u piggy -i <<'EOF'
while
    echo "Do you want to continue y/n?"
    read install_to_default
    [[ -z $install_to_default || $install_to_default != [yYnN] ]]
    do echo "The response is invalid. A valid response is y or n."; done
EOF
2 Answers

The stdin of the sudo process has been redirected to the here-document << and the read command in the loop doesn't wait for the user's input on console. Please try to change the read line to:

read -u 1 install_to_default

Technically it may not be the best idea to use descriptor 1 for the purpose. Strictly we should use other descriptor such as 3 with the -C 4 option to the sudo command. But this solution will require to change the sudoers policy which may rather cause more problems.

You cannot read user input this way because the input stream is already captured by the here-document script.

If you want to read user input from the terminal, while using a here-document as the sudo script, then read from /dev/tty

sudo -u piggy -i <<'EOF'
while
    printf %s\\n "Do you want to continue y/n?"
    read -r install_to_default </dev/tty
    [ -z "$install_to_default" ] || [ -n "${install_to_default%[yYnN]}" ]
    do
      printf %s\\n "The response is invalid. A valid response is y or n."
    done
EOF
Related