¿Cómo le solicito confirmación a un usuario en el script bash? [duplicar]

Resuelto Tom asked hace 15 años • 10 respuestas

Quiero hacer un rápido "¿estás seguro?" Solicite confirmación en la parte superior de un script bash potencialmente peligroso, ¿cuál es la mejor y más fácil manera de hacer esto?

Tom avatar Dec 11 '09 09:12 Tom
Aceptado
read -p "Are you sure? " -n 1 -r
echo    # (optional) move to a new line
if [[ $REPLY =~ ^[Yy]$ ]]
then
    # do dangerous stuff
fi

Incorporé la sugerencia de levislevis85-n (¡gracias!) y agregué la opción de readaceptar un carácter sin necesidad de presionar Enter. Puede utilizar uno o ambos.

Además, la forma negada podría verse así:

read -p "Are you sure? " -n 1 -r
echo    # (optional) move to a new line
if [[ ! $REPLY =~ ^[Yy]$ ]]
then
    [[ "$0" = "$BASH_SOURCE" ]] && exit 1 || return 1 # handle exits from shell or function but don't exit interactive shell
fi

Sin embargo, como señaló Erich, en algunas circunstancias, como un error de sintaxis causado por la ejecución del script en el shell incorrecto, la forma negada podría permitir que el script continúe con "cosas peligrosas". ifEl modo de fallo debería favorecer el resultado más seguro, por lo que sólo se debería utilizar el primero, el no negado .

Explicación:

El readcomando genera el mensaje ( -p "prompt") luego acepta un carácter ( -n 1) y acepta barras invertidas literalmente ( -r) (de lo contrario read, vería la barra invertida como un escape y esperaría un segundo carácter). La variable predeterminada para readalmacenar el resultado es $REPLYsi no proporciona un nombre como este:read -p "my prompt" -n 1 -r my_var

La ifdeclaración utiliza una expresión regular para comprobar si el carácter coincide $REPLY( =~) con una "Y" mayúscula o minúscula. La expresión regular utilizada aquí dice "una cadena que comienza ( ^) y consta únicamente de uno de una lista de caracteres en una expresión entre corchetes ( [Yy]) y termina ( $)". Los anclajes ( ^y $) impiden que coincidan cadenas más largas. En este caso ayudan a reforzar el límite de un carácter establecido en el readcomando.

La forma negada utiliza el operador lógico "no" ( !) para hacer coincidir ( =~) cualquier carácter que no sea "Y" o "y". Una forma alternativa de expresar esto es menos legible y, en mi opinión, no expresa tan claramente la intención en este caso. Sin embargo, así es como se vería:if [[ $REPLY =~ ^[^Yy]$ ]]

Dennis Williamson avatar Dec 11 '2009 02:12 Dennis Williamson

caso de uso/esac.

read -p "Continue (y/n)?" choice
case "$choice" in 
  y|Y ) echo "yes";;
  n|N ) echo "no";;
  * ) echo "invalid";;
esac

ventaja:

  1. más ordenado
  2. puede usar la condición "O" más fácilmente
  3. Puede usar un rango de caracteres, por ejemplo, [yY][eE][sS] para aceptar la palabra "sí", donde cualquiera de sus caracteres puede estar en minúsculas o en mayúsculas.
ghostdog74 avatar Dec 11 '2009 03:12 ghostdog74

Pruebe el readshell incorporado:

read -p "Continue (y/n)?" CONT
if [ "$CONT" = "y" ]; then
  echo "yaaa";
else
  echo "booo";
fi
Adam Hupp avatar Dec 11 '2009 02:12 Adam Hupp

De esta manera obtienes 'y' 'sí' o 'Entrar'

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

Si estás usando zsh prueba esto:

read "response?Are you sure ? [Y/n] "
response=${response:l} #tolower
if [[ $response =~ ^(y| ) ]] || [[ -z $response ]]; then
    your-action-here
fi
SergioAraujo avatar May 12 '2013 14:05 SergioAraujo