2010-07-12 14 views
158

En este caso particular, me gustaría añadir una confirmación en Bash paraEn Bash, cómo agregar "¿Estás seguro [Y/n]" de algún comando o alias?

 
Are you sure? [Y/n] 

para Mercurial hg push ssh://[email protected]//somepath/morepath, que es en realidad un alias. ¿Hay un comando estándar que se pueda agregar al alias para lograrlo?

La razón es que hg push y hg out pueden parecer similares y, a veces cuando quiero hgoutrepo, me accidentlly puede escribir hgpushrepo (ambos son alias).

Actualización: si puede ser algo así como un comando integrado con otro comando, como por ejemplo: confirm && hg push ssh://... eso sería genial ... sólo un comando que puede pedir una yes o no y continuar con la Descanse si yes.

+1

Es probable que desee utilizar un [Función] (http://mywiki.wooledge.org/BashFAQ/080) en lugar de un alias.De 'info bash':" Para casi cualquier propósito, las funciones de shell son preferibles a los alias ". –

+0

realmente? incluso para aquellos como 'ls -l' o' rm -i'? –

+5

Para * casi * cada, no * cada *. Por cierto, ** nunca ** haga algo como 'alias rm = 'rm -i''. Un día, cuando más lo necesites, el alias no estará allí y ¡'boom!' Se perderá algo importante. –

Respuesta

243

Estas son formas más compactas y versátiles de Hamish's answer. Ellos se encargan de cualquier mezcla de letras mayúsculas y minúsculas:

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

O, para Bash> = versión 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 

Nota: Si $response es una cadena vacía, se le dará un error. Para solucionarlo, simplemente agregue comillas: "$response". - Utilice siempre comillas dobles en las variables que contengan cadenas (por ejemplo, prefiera usar "[email protected]" en su lugar [email protected]).

O, Bash 4.x:

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

Editar:

En respuesta a su edición, aquí te mostramos cómo crear y utilizar un comando confirm basado en la primera versión en mi respuesta (que funcionaría de manera similar con los otros dos):

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 
} 

Para utilizar esta función:

confirm && hg push ssh://.. 

o

confirm "Would you really like to do a push?" && hg push ssh://.. 
+7

En realidad, debe ser [y/N] y no [Y/n] para la prueba actual. –

+0

Vale la pena mencionar que si desea marcar 'no igual a' en el segundo ejemplo, debe emitir la variable' $ response'. Por ejemplo: 'si [[! $ respuesta = ~^([yY] [eE] [sS] | [yY]) $]] '. –

+0

@ JoãoCunha: Eso sería "no coincidencia" en lugar de "no igual" ya que '= ~' es el operador de coincidencia de expresiones regulares. –

18

Aquí hay más o menos un fragmento que desea. Déjame saber cómo reenviar los argumentos.

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 

cuidado con los yes | command name here :)

+0

Estaría decepcionado si Jon Skeet obtiene más puntos en esta respuesta. –

8

Para evitar de manera explícita la comprobación de estas variantes del 'sí' se puede utilizar el operador de fiesta expresión regular '= ~' con una expresión regular:

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

Eso prueba si la entrada del usuario comienza con 'y' o 'Y' y es seguido por cero o más 'es'.

+2

Yeseseseseseseseseseseseseseseseseseseseses – Dev

3

Añadir lo siguiente a su archivo/etc/bashrc. Este script agrega una "función" residente en lugar de un alias llamado "confirmar".


function confirm() 
{ 
#alert the user what they are about to do. 
echo "About to [email protected]"; 
#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 
       "[email protected]" 
       ;; 
    *) 
       #Otherwise exit... 
       echo "ciao..." 
       exit 
       ;; 
esac 
} 
+0

Agradable. Algunas correcciones menores, sin embargo: debe poner comillas dobles alrededor de '$ response' y' $ @ 'para evitar errores de comparación, hay algunos puntos y comas redundantes, y la condición' * 'debe regresar, no salir. –

+0

Para que quede claro, son solo los puntos y comas al final de algunas afirmaciones que son innecesarias. –

+0

ok eliminado los puntos y comas. los viejos hábitos mueren duro :) – MattyV

0

Esto no es exactamente un "pidiendo sí o no", pero sólo un truco: alias de la hg push ... no a hgpushrepo pero a hgpushrepoconfirmedpush y por el tiempo que puedo explicar todo el asunto, el el cerebro izquierdo ha hecho una elección lógica.

+0

¡Pero sabes que usarás la tecla 'TAB'! –

+0

bien, cierto, pero al menos echaré un vistazo al comando y veré que es raro y lo pienso dos veces antes de presionar Enter –

3
read -r -p "Are you sure? [Y/n]" response 
    response=${response,,} # tolower 
    if [[ $response =~ ^(yes|y|) ]] || [[ -z $response ]]; then 
     your-action-here 
    fi 
+0

Entonces, ¿un carácter de espacio significa sí? – Xen2050

+0

Todos excepto 'sí o sí' confirmarán la acción, ¡así que tienes razón! @ xen2050 – SergioAraujo

1

tarde al juego, pero creó otra variante más de los confirm funciones de las respuestas anteriores:

confirm() 
{ 
    read -r -p "$(echo [email protected]) ? [y/N] " YESNO 

    if [ "$YESNO" != "y" ]; then 
     echo >&2 "Aborting" 
     exit 1 
    fi 

    CMD="$1" 
    shift 

    while [ -n "$1" ]; do 
     echo -en "$1\0" 
     shift 
    done | xargs -0 "$CMD" || exit $? 
} 

Para usarlo:

confirm your_command 

Características:

  • imprime su comando como parte de la solicitud de
  • pasa argumentos a través con el delimitador NULL
  • conserva el estado de salida del comando

Errores:

  • echo -en obras con bash pero puede fallar en su shell
  • puede fallar si los argumentos interfieren con echo o xargs
  • un trillón de otros insectos porque shell scripting es difícil
1

intento,

#!/bin/bash 
pause() 
{ 
REPLY=Y 
while [ "$REPLY" == "Y" ] || [ "$REPLY" != "y" ] 
do 
    echo -e "\t\tPress 'y' to continue\t\t\tPress 'n' to quit" 
    read -n1 -s 
     case "$REPLY" in 
     "n") exit      ;; 
     "N") echo "case sensitive!!" ;; 
     "y") clear      ;; 
     "Y") echo "case sensitive!!" ;; 
     *) echo "$REPLY is Invalid Option"  ;; 
esac 
done 
} 
pause 
echo "Hi" 
7

Las confirmaciones se pasan por alto fácilmente con retornos de carro, y me parece que es útil para impulsar continuamente por una entrada válida.

Aquí hay una función para hacer esto fácil. "entrada inválida" aparece en rojo si Y | N no se recibe, y se le solicita al usuario nuevamente.

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 

Puede cambiar el indicador predeterminado al pasar un argumento

0
No

la misma, pero la idea que funciona de todos modos.

#!/bin/bash 
i='y' 
while [ ${i:0:1} != n ] 
do 
    # Command(s) 
    read -p " Again? Y/n " i 
    [[ ${#i} -eq 0 ]] && i='y' 
done 

Salida:
vez más? S/n N
¿Otra vez? S/n Cualquier cosa
¿Otra vez? S/n 7
¿Otra vez? S/n &
¿Otra vez? S/n nsijf
$

Ahora solo se verifica el 1er carácter de $ que leo.

2

Bueno, aquí está mi versión de confirm, modificado a partir de James uno:

function confirm() { 
    local response msg="${1:-Are you sure} (y/[n])? "; shift 
    read -r $* -p "$msg" response || echo 
    case "$response" in 
    [yY][eE][sS]|[yY]) return 0 ;; 
    *) return 1 ;; 
    esac 
} 

Estos cambios son:

  1. uso local para evitar que los nombres de variables colisionen
  2. read uso $2 $3 ... a controle su acción, por lo que puede usar -n y -t
  3. si read salidas sin éxito, echo un avance de línea para la belleza
  4. mi Git on Windows sólo tiene bash-3.1 y no tiene true o false, a fin de utilizar return lugar. Por supuesto, esto también es compatible con bash-4.4 (el actual en Git para Windows).
  5. use el estilo de IPython "(y/[n])" para indicar claramente que "n" es el valor predeterminado.
0

A continuación código es la combinación de dos cosas

  1. shopt -s nocasematch que se hará cargo del caso insensible

  2. y si la condición de que acepte tanto la entrada o bien se pasa sí, sí ,Si.

    shopt -s nocasematch

    si [[sed-4.2.2 $ line = ~. (Sí | y) $]]

    luego la salida 0

    fi

0

Aquí está mi solución que usa regex localizado. Entonces en alemán también "j" para "Ja" se interpretaría como sí.

El primer argumento es la pregunta, si el segundo argumento es "y", entonces sí sería la respuesta predeterminada; de lo contrario, no sería la respuesta predeterminada. El valor de retorno es 0 si la respuesta fue "sí" y 1 si la respuesta fue "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]} 
} 

Aquí es un uso básico

# 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]? : " 
Cuestiones relacionadas