3

I am trying to implement confirmation prompt with a bash script but for some reason, prompt won't wait for user input. I've tried many examples but no luck so far. I am on MacOS if it makes any difference.

Just a few examples I tried (All copy+paste from other answers in SO):

#!/bin/bash

read -p "Are you sure? " -n 1 -r
echo    # (optional) move to a new line
if [[ $REPLY =~ ^[Yy]$ ]]
then
    # do dangerous stuff
fi

#!/bin/bash

read -p "Continue (y/n)?" CONT
if [ "$CONT" = "y" ]; then
  echo "yaaa";
else
  echo "booo";
fi

#!/bin/bash

while true; do
read -rsn1 input
if [ "$input" = "a" ]; then
    echo "hello world"
fi
done

#!/bin/bash

read -p "Continue (y/n)?" choice
case "$choice" in
  y|Y ) echo "yes";;
  n|N ) echo "no";;
  * ) echo "invalid";;
esac

This doesn't even prompt anything:

#!/bin/bash
read -n 1 -s -r -p "Press any key to continue"
glenn jackman
  • 238,783
  • 38
  • 220
  • 352
BentCoder
  • 12,257
  • 22
  • 93
  • 165
  • 2
    It is unclear. What is not working and what is expected behavior? – anubhava Feb 06 '18 at 10:25
  • 1. Run the bash script. 2. Prompt user "Do you want to continue? [y/N]" 3. User presses any key. 4. If "y" then do something otherwise continue. PROBLEM: Step 2 just prints message on terminal and finished without prompting user. – BentCoder Feb 06 '18 at 10:39
  • how the script is launched? – Nahuel Fouilleul Feb 06 '18 at 10:44
  • It is actually a `.git/hooks/commit-msg` file so when user runs `git commit -m 'Hello'`, `commit-msg` gets triggered/launched. – BentCoder Feb 06 '18 at 10:45
  • 4
    see this answer [how-do-i-prompt-the-user-from-within-a-commit-msg-hook](https://stackoverflow.com/questions/3417896/how-do-i-prompt-the-user-from-within-a-commit-msg-hook), seems standard input is closed, indeed you can add `ls -l /dev/fd/` to see : 0 -> /dev/null, another solution, may be exec 0<&1 – Nahuel Fouilleul Feb 06 '18 at 10:53
  • @NahuelFouilleul It seems to be working. Thank you for the link. – BentCoder Feb 06 '18 at 11:00
  • @NahuelFouilleul or BentCoder, one of you should provide an answer that can be accepted. This is a useful question for other people and it should have an accepted answer. – glenn jackman Feb 06 '18 at 14:11
  • @glennjackman I've added the solution below. – BentCoder Feb 06 '18 at 14:49

3 Answers3

6

Changed to answer from comment : in commit-msg hook it seems standard input is closed, indeed this can be checked adding following command

ls -l /dev/fd/

which gives

... 0 -> /dev/null

as mentioned in this post

exec 0< /dev/tty

will restore standard input to tty, another solution as noticed standard output and error are still redirected to tty

exec 0<&1
Nahuel Fouilleul
  • 18,726
  • 2
  • 31
  • 36
5

The original question has the important part missing and it is my fault not making it very clear in very first place. It became apparent after @NahuelFouilleul's comment. The confirmation/question prompt was not waiting for user to hit a key. The reason was because my bash script was being called by a git hook. Things seem to be done in slightly different way in such cases. The solution is below but the original answer is here.

#!/bin/bash

exec < /dev/tty

while true; do
    read -p "Accepting the offer? (y/n) " answer

    if [[ $answer =~ ^[Yy]$ ]] ;
    then
        echo "Accepted"
    else
        echo "Not accepted"
    fi

    break
done
BentCoder
  • 12,257
  • 22
  • 93
  • 165
-1

Try this:

echo -n "Continue  (y/n)?"
read CONT
if [ "$CONT" = "n" ]
then
  echo "NO"
else
  echo "YES"
fi

the echo -n means no newline

developer
  • 690
  • 7
  • 16