views:

232

answers:

7

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 1 command that ask for a yes and continue with the rest if so.

+5  A: 

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 :)

Hamish Grubijan
I would be disappointed if Jon Skeet scores more points on this answer.
Hamish Grubijan
+1  A: 

To avoid explicitly checking for these variants of 'yes' you could use the bash regular expression operator '=~' with a regular expression:

read -p "Are you sure you want to continue? <y/N> " prompt
if [[ $prompt =~ [yY](es)* ]]
then
(etc...)

That tests whether the user input starts with 'y' or 'Y' and is followed by zero or more 'es's.

+6  A: 

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

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://..
Dennis Williamson
+2  A: 

Add the following to your /etc/bashrc file. This script adds a resident "function" instead of an alias called "confirm".


function confirm( )
{
#alert the user what they are about to do.
echo "About to $@....";
#confirm with the user
read -r -p "Are you sure? [Y/n]" response
case "$response" in
    [yY][eE][sS]|[yY]) 
              #if yes, then execute the passed parameters
               "$@"
               ;;
    *)
              #Otherwise exit...
              echo "ciao..."
              exit
              ;;
esac
}
MattyV
Nice. Some minor corrections, though: you should put double-quotes around `$response` and `$@` to avoid misparses, there are some redundant semicolons, and the `*` condition should return, not exit.
Gordon Davisson
Just to be clear, it's the single semicolons at the end of some statements that are unnecessary.
Dennis Williamson
ok removed the semi colons. old habits die hard :)
MattyV
A: 

This isn't exactly an "asking for yes or no" but just a hack: alias the hg push ... not to hgpushrepo but to hgpushrepoconfirmedpush and by the time I can spell out the whole thing, the left brain has made a logical choice.

動靜能量
But you know that you will use the `TAB` key!
Hamish Grubijan
hee hee, i am not used to using `TAB` yet
動靜能量
A: 
read -r -p "Are you sure? [Y/n]" response
response=${response,,}    # tolower
if [[ $response =~ ^(yes|y| ) ]]

# if only press Enter we need detect this condiction
A: 

This may be a hack:

as in question http://stackoverflow.com/questions/3400799/is-xargs-p-a-good-way-to-prompt-for-confirmation-before-running-any-command-on

we can

echo ssh://[email protected]//somepath/morepath | xargs -p hg push

of course, this will be set as an alias, like hgpushrepo

動靜能量