简体   繁体   中英

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 .

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

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
      ;;

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

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

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

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 ay/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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM