Bash ou condição em uma instrução while

Bash ou condição em uma instrução while

Quero escrever um script em bash que verifique a entrada do usuário se for igual a "stringA" ou "stringB" e caso seja igual a uma dessas strings deve imprimir a entrada do usuário. Meu código é:

#!/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

Infelizmente, esse código não funciona e faz loop infinito. Só posso comparar se the $resulté igual a uma das strings removendo the ||e a segunda parte do loop while. Tentei substituir o ||por -omas recebi o seguinte erro:

./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' 

Responder1

Isso é porque você deseja usar &&, não ||.

Você deseja repetir o loop se o resultado não for stringA E não for stringB. Nenhuma string pode ser igual a ambas, o que encerraria seu loop.

Você também pode usar um padrão em [[ ... ]]:

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

Responder2

#!/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

No textspeech enquanto não o resultado é stringa ou o resultado é stringb do...

esteja ciente de "suas variáveis, caso contrário você receberá um erro se a var $resultestiver vazia.

Responder3

O problema no seu código é que seu loop faz um loop while $resultnão é o mesmo queambos stringAe stringBao mesmo tempo). Você pode querer usar

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

ou

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

Para fazer com que um usuário escolha uma dentre algumas opções, não faça com que ele digite sequências longas. Em vez disso, forneça a eles um menu simples para escolher.

Sugestão:

#!/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"

Executando isto:

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

Responder4

Uma shvariante, e removeria os problemas associados ao ${var,,}uso do código do idioma para converter strings (letras minúsculas Inão são ipara todos, por exemplo):

#! /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

informação relacionada