Pregunta ¿Cómo solicito la entrada Sí / No / Cancel en un script de shell de Linux?


Quiero pausar la entrada en un script de shell e indicarle al usuario las opciones. La pregunta estándar del tipo 'Sí, No o Cancelar'. ¿Cómo puedo lograr esto en un típico aviso de bash?


1100
2017-10-22 17:03


origen


Respuestas:


El método más simple y más ampliamente disponible para obtener la entrada del usuario en un intérprete de comandos del shell es el read mando. La mejor manera de ilustrar su uso es una demostración simple:

while true; do
    read -p "Do you wish to install this program?" yn
    case $yn in
        [Yy]* ) make install; break;;
        [Nn]* ) exit;;
        * ) echo "Please answer yes or no.";;
    esac
done

Otro método, señalado por Steven Huwig, es Bash's select mando. Aquí está el mismo ejemplo usando select:

echo "Do you wish to install this program?"
select yn in "Yes" "No"; do
    case $yn in
        Yes ) make install; break;;
        No ) exit;;
    esac
done

Con select no necesita desinfectar la entrada: muestra las opciones disponibles y escribe un número correspondiente a su elección. También se repite automáticamente, por lo que no es necesario while true bucle para volver a intentar si dan entrada no válida.

Además, echa un vistazo a la excelente respuesta por F. Hauri.


1269
2017-10-22 17:08



Al menos cinco respuestas para una pregunta genérica.

Dependiendo de

  •  obediente: podría trabajar en sistemas pobres con genéricos  ambientes
  •  específico: utilizando lo que se llama bashisms

y si tu quieres

  • simple pregunta / respuesta `` en línea '' (soluciones genéricas)
  • bonitas interfaces formateadas, como  o más gráficos usando libgtk o libqt ...
  • utilizar la poderosa capacidad de historial de readline

1. Soluciones genéricas POSIX

Podrías usar el read comando, seguido de if ... then ... else:

echo -n "Is this a good question (y/n)? "
read answer

# if echo "$answer" | grep -iq "^y" ;then


374
2018-01-10 10:53



echo "Please enter some input: "
read input_variable
echo "You entered: $input_variable"

333
2017-10-22 17:08



Puedes usar el built-in leer comando; Utilizar el -p opción para avisar al usuario con una pregunta.

Desde BASH4, ahora puede usar -i sugerir una respuesta, por lo que el usuario solo tiene que presionar return para ingresarlo:

read -e -p "Enter the path to the file: " -i "/usr/local/etc/" FILEPATH
echo $FILEPATH

(Pero recuerda usar la opción "readline" -e para permitir la edición de línea con las teclas de flecha)

Si desea una lógica de "sí / no", puede hacer algo como esto:

read -e -p "
List the content of your home dir ? [Y/n] " YN

[[ $YN == "y" || $YN == "Y" || $YN == "" ]] && ls -la ~/

117
2018-05-13 04:44



Bash tiene seleccionar para este propósito.

select result in Yes No Cancel
do
    echo $result
done

95
2017-10-22 18:14



read -p "Are you alright? (y/n) " RESP
if [ "$RESP" = "y" ]; then
  echo "Glad to hear it"
else
  echo "You need more bash programming"
fi

51
2018-02-03 13:23



Aquí hay algo que armé:

#!/bin/sh

promptyn () {
    while true; do
        read -p "$1 " yn
        case $yn in
            [Yy]* ) return 0;;
            [Nn]* ) return 1;;
            * ) echo "Please answer yes or no.";;
        esac
    done
}

if promptyn "is the sky blue?"; then
    echo "yes"
else
    echo "no"
fi

Soy un principiante, así que tome esto con un grano de sal, pero parece funcionar.


27
2017-08-30 17:59



Usted quiere:

  • Comandos Bash integrados (es decir, portátiles)
  • Verifique TTY
  • Respuesta predeterminada
  • Se acabó el tiempo
  • Pregunta coloreada

Retazo

do_xxxx=y                      # In batch mode => Default is Yes
[[ -t 0 ]] &&                  # If TTY => Prompt the question
read -n 1 -p $'\e[1;32m
Do xxxx? (Y/n)\e[0m ' do_xxxx  # Store the answer in $do_xxxx
if [[ $do_xxxx =~ ^(y|Y|)$ ]]  # Do if 'y' or 'Y' or empty
then
    xxxx
fi

Explicaciones

  • [[ -t 0 ]] && read ... => Comando de llamada read si TTY
  • read -n 1 => Espera un personaje
  • $'\e[1;32m ... \e[0m ' => Imprimir en verde
    (verde está bien porque es legible en ambos fondos blanco / negro)
  • [[ $do_xxxx =~ ^(y|Y|)$ ]] => bash regex

Timeout => La respuesta predeterminada es No

do_xxxx=y
[[ -t 0 ]] && {                   # Timeout 5 seconds (read -t 5)
read -t 5 -n 1 -p $'\e[1;32m
Do xxxx? (Y/n)\e[0m ' do_xxxx ||  # read 'fails' on timeout
do_xxxx=n ; }                     # Timeout => answer No
if [[ $do_xxxx =~ ^(y|Y|)$ ]]
then
    xxxx
fi

22
2017-12-18 11:36