Search code examples
bashaliasconfirmation

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


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://[email protected]//somepath/morepath, which is actually an alias. Is there a standard command that can be added to the alias to achieve it?

The reason is that hg push and hg out can sound similar and sometimes when I want hgoutrepo, I may accidentlly type hgpushrepo (both are aliases).

Update: if it can be something like a built-in command with another command, such as: confirm && hg push ssh://... that'd be great... just a command that can ask for a yes or no and continue with the rest if yes.


Solution

  • 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://..