¿Cómo solicito confirmación a un usuario en el script bash?

Quiero poner un rápido “¿estás seguro?” solicita la confirmación en la parte superior de un script de bash potencialmente peligroso, ¿cuál es la forma más fácil / mejor de hacer esto?

read -p "Are you sure? " -n 1 -r echo # (optional) move to a new line if [[ $REPLY =~ ^[Yy]$ ]] then # do dangerous stuff fi 

Editar :

Incorporé la sugerencia de levislevis85 (¡gracias!) Y agregué la opción -n para read para aceptar un carácter sin la necesidad de presionar Enter . Puedes usar uno o ambos de estos.

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 syntax causado por la ejecución del script en el shell incorrecto, el formulario negado podría permitir que el script continúe con el “material peligroso”. El modo de falla debe favorecer el resultado más seguro, por lo que solo se debe usar el primero, no negado.

use case / 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 limpio
  2. puede usar la condición “O” más fácil
  3. puede usar el rango de caracteres, por ejemplo [yY] [eE] [sS] para aceptar la palabra “sí”, donde cualquiera de sus caracteres puede estar en minúscula o en mayúscula.

De esta forma obtienes ‘y’ ‘yes’ o ‘Enter’

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

Si está usando zsh intente esto:

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

Prueba el builtin de read shell:

 read -p "Continue (y/n)?" CONT if [ "$CONT" = "y" ]; then echo "yaaa"; else echo "booo"; fi 

Aquí está la función que uso:

 function ask_yes_or_no() { read -p "$1 ([y]es or [N]o): " case $(echo $REPLY | tr '[AZ]' '[az]') in y|yes) echo "yes" ;; *) echo "no" ;; esac } 

Y un ejemplo usándolo:

 if [[ "no" == $(ask_yes_or_no "Are you sure?") || \ "no" == $(ask_yes_or_no "Are you *really* sure?") ]] then echo "Skipped." exit 0 fi # Do something really dangerous... 
  • La salida siempre es “sí” o “no”
  • Es “no” por defecto
  • Todo excepto “y” o “sí” devuelve “no”, por lo que es bastante seguro para un script de bash peligroso
  • Y no distingue entre mayúsculas y minúsculas, “Y”, “Sí” o “SÍ” funcionan como “sí”.

Espero que te guste,
¡Aclamaciones!

Esto que encontré en otra parte, ¿hay una mejor versión posible?

 read -p "Are you sure you wish to continue?" if [ "$REPLY" != "yes" ]; then exit fi 
 [[ -f ./${sname} ]] && read -p "File exists. Are you sure? " -n 1 [[ ! $REPLY =~ ^[Yy]$ ]] && exit 1 

Utilicé esto en una función para buscar un archivo existente y preguntar antes de sobrescribir.

 #!/bin/bash echo Please, enter your name read NAME echo "Hi $NAME!" if [ "x$NAME" = "xyes" ] ; then # do something fi 

Soy un script corto para leer en bash y repetir los resultados.

qnd: uso

 read VARNAME echo $VARNAME 

para una respuesta de una línea sin soporte de lectura. Luego prueba $ VARNAME como quieras.

 echo are you sure? read x if [ "$x" = "yes" ] then # do the dangerous stuff fi