Bash o condición en una declaración while

Bash o condición en una declaración while

Quiero escribir un script en bash que verifique la entrada del usuario si es igual a "cadenaA" o "cadenaB" y en caso de que sea igual a una de estas cadenas, debería imprimir la entrada del usuario. Mi código es:

#!/bin/bash

echo "Please enter your choice (stringA or stringB): "
read result

while [[ (${result,,} != 'stringa') || (${result,,} != 'stringb') ]]; do
        echo Please enter only stringA or stringB:
        read result
done

echo "You have selected $result!"

exit

Lamentablemente, este código no funciona y se repite infinitamente. Solo puedo comparar si $resultes igual a una de las cadenas que eliminan ||y la segunda parte del bucle while. Intenté reemplazar ||con -opero recibí el siguiente error:

./chk.sh: line 12: syntax error in conditional expression
./chk.sh: line 12: syntax error near `-o'
./chk.sh: line 12: `while [[ (${result,,} != 'stringa') -o (${result,,} != 'stringb') ]]; do' 

Respuesta1

Eso es porque quieres usarlo &&, no ||.

Desea repetir el ciclo si el resultado no es una cadenaA Y no es una cadenaB. Ninguna cadena puede ser igual a ambas, lo que podría terminar el ciclo.

También puedes usar un patrón en [[ ... ]]:

while [[ ${result,,} != string[ab] ]]

Respuesta2

#!/bin/bash

echo "Please enter your choice (stringA or stringB): "
read result

while ! [ "${result,,}" = 'stringa' -o "${result,,}" = 'stringb' ]; do
        echo Please enter only stringA or stringB:
        read result
done

echo "You have selected $result!"

exit

En discurso de texto, mientras el resultado no sea stringa o el resultado sea stringb, haga...

tenga en cuenta "sus variables; de lo contrario, obtendrá un error si la var $resultestá vacía.

Respuesta3

El problema en su código es que su bucle se repite mientras $resultno es lo mismo queambos stringAy stringBal mismo tiempo). Es posible que desee utilizar

while [[ "${result,,}" != 'stringa' ]] && [[ "${result,,}" != 'stringb') ]]

o

until [[ "${result,,}" == 'stringa' ]] || [[ "${result,,}" == 'stringb') ]]

Para lograr que un usuario elija una de varias opciones, no le pida que escriba cadenas largas. En su lugar, proporcióneles un menú sencillo para elegir.

Sugerencia:

#!/bin/bash

PS3='Your choice: '
select result in 'stringA' 'stringB'; do
    case $REPLY in
        [12])
            break
            ;;
        *)
            echo 'Invalid choice' >&2
    esac
done

printf 'You picked %s!\n' "$result"

Ejecutando esto:

$ bash script.sh
1) stringA
2) stringB
Your choice: 3
Invalid choice
Your choice: 2
You picked stringB!

Respuesta4

Una shvariante que eliminaría los problemas asociados con ${var,,}el uso de la configuración regional para convertir cadenas (las minúsculas Ino son ipara todos, por ejemplo):

#! /bin/sh -
while true; do
  printf %s "Please enter your choice (stringA or stringB): "
  IFS= read -r result || exit # exit on EOF
  case $result in
    ([sS][tT][rR][iI][nN][gG][aAbB]) break
  esac
  echo >&2 Invalid choice.
done

información relacionada