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

2

Eu quero escrever um script no bash que esteja verificando a entrada do usuário se for igual a "stringA" ou "stringB" e, caso seja igual a uma dessas strings, ele 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 este código não funciona e faz um loop infinitamente. Eu só posso comparar se o $result é igual a uma das seqüências de caracteres removendo o || e a segunda parte do loop while. Eu tentei substituir o || por -o , mas 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' 
    
por Georgе Stoyanov 23.11.2017 / 17:07

4 respostas

3

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 acabaria com o loop.

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

while [[ ${result,,} != string[ab] ]]
    
por 23.11.2017 / 17:11
2

O problema em seu código é que o loop faz um loop enquanto $result não é o mesmo que ambos stringA e stringB (ao mesmo tempo). Você pode querer usar

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

ou

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

Para que um usuário escolha uma das poucas opções, não faça com que ele digite strings 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 isso:

$ bash script.sh
1) stringA
2) stringB
Your choice: 3
Invalid choice
Your choice: 2
You picked stringB!
    
por 04.06.2018 / 17:24
1
#!/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, embora não seja resultado stringa, o resultado é stringb ...

esteja ciente de " em torno de suas variáveis, senão você receberá um erro se o var $result estiver vazio.

    
por 23.11.2017 / 18:05
0

Uma variante sh e removeria os problemas associados a ${var,,} , que usa a localidade para converter sequências (por exemplo, minúscula I não é i para todos):

#! /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
    
por 04.06.2018 / 17:34