user898082
user898082

Reputation:

Shell user prompt (Y/n)

I just wanted to write a small sript for copying some files for my NAS, so I'm not very experienced in Shell-Scripting. I know that many command line tools on Linux use the following sheme for Yes/No inputs

Are you yure [Y/n]

where the capitalized letter indicates the standard action which would also be started by hitting Enter. Which is nice for a quick usage.

I also want to implement something like this, but I have some trouble with caching the Enter key. Here is what I got so far:

read -p "Are you sure? [Y/n] " response

    case $response in [yY][eE][sS]|[yY]|[jJ]|[#insert ENTER codition here#]) 

        echo
        echo files will be moved
        echo
        ;;
    *)
        echo
        echo canceld
        echo
        ;;
esac

I can add what ever I want but it just won't work with Enter.

Upvotes: 4

Views: 7197

Answers (6)

Varstahl
Varstahl

Reputation: 625

A few years passed since the question was asked, but since it's still relevant in searches I thought I'd provide the different method I ended up using.

I wanted to lock the question in place until a y/n/enter is pressed and without spamming the prompt request, so I (ab)used the -s echo suppression and came up with the following:

#!/bin/bash
echo -n "Confirm action [y/N]? "
while true; do
    read -sn1 response
    case "$response" in
        [yY]) echo 'y'; break;;
        [nN]|"") echo 'n'; exit 0;;
    esac
done

Upon N or Enter the script is ended, otherwise it just goes on as intended. The additional echos to output user choice is not necessary, but I left it in as a visual feedback.

Also, by moving the |"" around, you can default the enter key to either yes or no responses.

Upvotes: 1

user3554724
user3554724

Reputation: 31

Since you gave option [y/n], the code can be changed something like (edited):

#!/bin/bash

 while true
 do
   echo "Are you sure? [Y/n]?"
    read response
    case $(echo ${response:-Y}|tr '[:lower:]' '[:upper:]') in
        Y|YES)
            echo "files will be moved!"
            break
            ;;
        N|NO)
            echo "aborted!"
            exit
            ;;
        *)
            echo "incorrect selection!"
            ;;
    esac
done

Upvotes: 1

Keith Reynolds
Keith Reynolds

Reputation: 853

This has input validation that accepts "Y", "y", "an empty string" or "n" and "N" as valid input for the question [Y/n].

#!/bin/bash

while : ; do # colon is built into bash; and is always true. 
    read -n1 -p "Are you sure? [Y/n] " response
    echo 
    case "$response" in
        y|Y|"") echo "files will be moved"; break ;; # Break out of while loop
        n|N) echo -e "canceled"; break ;; # Break out of while loop
        *) echo "Invalid option given." ;;
    esac
done

Upvotes: 4

Aaron Okano
Aaron Okano

Reputation: 2343

Here's a quick solution:

read -p "Are you sure? [Y/n] " response

case $response in [yY][eE][sS]|[yY]|[jJ]|'') 

    echo
    echo files will be moved
    echo
    ;;
    *)
    echo
    echo canceled
    echo
    ;;
esac

Upvotes: 5

chepner
chepner

Reputation: 531165

If you are using bash 4, you can "pre-seed" the response with the default answer, so that you don't have to treat ENTER explicitly. (You can also standardize the case of response to simplify the case statement.

read -p "Are you sure? [Y/n] " -ei "y" response
response=${response,,}  # convert to lowercase
case $response in
    y|ye|yes)
      echo
      echo files will be moved
      echo
    ;;
    *)
      echo
      echo cancelled
      echo
      ;;

Upvotes: 5

anubhava
anubhava

Reputation: 785146

You should use read -n1

read -n1 -p "Are you sure? [Y/n] " response

case "$response" in 
   [yY]) echo "files will be moved";;
   ?) echo "canceled";;
esac

As per help read:

  -n nchars return after reading NCHARS characters rather than waiting
        for a newline, but honor a delimiter if fewer than NCHARS
        characters are read before the delimiter

Upvotes: 3

Related Questions