In Bash, how to add “Are you sure [Y/n]” to any command or alias?

前端 未结 17 2883
轮回少年
轮回少年 2020-11-29 15:11

In this particular case, I\'d like to add a confirm in Bash for

Are you sure? [Y/n]

for Mercurial\'s hg push ssh://username@www.example.com//some

相关标签:
17条回答
  • 2020-11-29 15:25
    read -r -p "Are you sure? [Y/n]" response
      response=${response,,} # tolower
      if [[ $response =~ ^(yes|y| ) ]] || [[ -z $response ]]; then
          your-action-here
      fi
    
    0 讨论(0)
  • 2020-11-29 15:30

    Confirmations are easily bypassed with carriage returns, and I find it useful to continually prompt for valid input.

    Here's a function to make this easy. "invalid input" appears in red if Y|N is not received, and the user is prompted again.

    prompt_confirm() {
      while true; do
        read -r -n 1 -p "${1:-Continue?} [y/n]: " REPLY
        case $REPLY in
          [yY]) echo ; return 0 ;;
          [nN]) echo ; return 1 ;;
          *) printf " \033[31m %s \n\033[0m" "invalid input"
        esac 
      done  
    }
    
    # example usage
    prompt_confirm "Overwrite File?" || exit 0
    

    You can change the default prompt by passing an argument

    0 讨论(0)
  • 2020-11-29 15:30

    Below code is combining two things

    1. shopt -s nocasematch that will take care of case insensitive

    2. and if condition that will accept both the input either you pass yes,Yes,YES,y.

      shopt -s nocasematch

      if [[ sed-4.2.2.$LINE =~ (yes|y)$ ]]

      then exit 0

      fi

    0 讨论(0)
  • 2020-11-29 15:33

    Here is my solution that using localised regex. So in german also "j" for "Ja" would be interpreted as yes.

    First argument is the question, if the second argument is "y" than yes would be the default answer otherwise no would be the default answer. The return value is 0 if the answer was "yes" and 1 if the answer was "no".

    function shure(){
        if [ $# -gt 1 ] && [[ "$2" =~ ^[yY]*$ ]] ; then
            arg="[Y/n]"
            reg=$(locale noexpr)
            default=(0 1)
        else
            arg="[y/N]"
            reg=$(locale yesexpr)
            default=(1 0)
        fi
        read -p "$1 ${arg}? : " answer
        [[ "$answer" =~ $reg ]] && return ${default[1]} || return ${default[0]}
    }
    

    Here is a basic usage

    # basic example default is no
    shure "question message" && echo "answer yes" || echo "answer no"
    # print "question message [y/N]? : "
    
    # basic example default set to yes
    shure "question message" y && echo "answer yes" || echo "answer no"
    # print "question message [Y/n]? : "
    
    0 讨论(0)
  • 2020-11-29 15:34

    These are more compact and versatile forms of Hamish's answer. They handle any mixture of upper and lower case letters:

    read -r -p "Are you sure? [y/N] " response
    case "$response" in
        [yY][eE][sS]|[yY]) 
            do_something
            ;;
        *)
            do_something_else
            ;;
    esac
    

    Or, for Bash >= version 3.2:

    read -r -p "Are you sure? [y/N] " response
    if [[ "$response" =~ ^([yY][eE][sS]|[yY])$ ]]
    then
        do_something
    else
        do_something_else
    fi
    

    Note: If $response is an empty string, it will give an error. To fix, simply add quotation marks: "$response". – Always use double quotes in variables containing strings (e.g.: prefer to use "$@" instead $@).

    Or, Bash 4.x:

    read -r -p "Are you sure? [y/N] " response
    response=${response,,}    # tolower
    if [[ "$response" =~ ^(yes|y)$ ]]
    ...
    

    Edit:

    In response to your edit, here's how you'd create and use a confirm command based on the first version in my answer (it would work similarly with the other two):

    confirm() {
        # call with a prompt string or use a default
        read -r -p "${1:-Are you sure? [y/N]} " response
        case "$response" in
            [yY][eE][sS]|[yY]) 
                true
                ;;
            *)
                false
                ;;
        esac
    }
    

    To use this function:

    confirm && hg push ssh://..
    

    or

    confirm "Would you really like to do a push?" && hg push ssh://..
    
    0 讨论(0)
  • 2020-11-29 15:34

    Here is roughly a snippet that you want. Let me find out how to forward the arguments.

    read -p "Are you sure you want to continue? <y/N> " prompt
    if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]
    then
      # http://stackoverflow.com/questions/1537673/how-do-i-forward-parameters-to-other-command-in-bash-script
    else
      exit 0
    fi
    

    Watch out for yes | command name here :)

    0 讨论(0)
提交回复
热议问题