Processando uma resposta Sim / Não do usuário Bash

11

Isso pode muito bem ser estupidez da minha parte. Gostaria de aceitar respostas Sim / Não, Verdadeiro / Falso no meu script Bash:

test.sh

#!/bin/bash

ARGUMENT=$1

echo User passed in $ARGUMENT

OPTARG=${ARGUMENT:0:1}

if [[ "$OPTARG" -eq 0 ]] || [[ "${OPTARG^^}" == "N" ]]; then
    echo Decline
elif [[ "$OPTARG" -eq 1 ]] || [[ "${OPTARG^^}" == "Y" ]]; then
    echo Accept
else
    echo Invalid argument
fi

Aqui estão alguns resultados de amostra:

./test.sh 0

User passed in 0
Decline

./test.sh 1

User passed in 1
Accept

./test.sh 2

User passed in 2
Invalid argument

./test.sh Não

User passed in No
Decline

Agora o saltador. Por que [[ "${OPTARG^^}" == "N" ]]retornar true para qualquer string?

./test.sh Sim

User passed in Yes
Decline

./test.sh ThisShouldNotMatch

User passed in ThisShouldNotMatch
Decline
i_grok
fonte
o que acontece se você citar isso? OPTARG = "$ {ARGUMENT: 0: 1}"
mikeserv 15/03
1
Deixa pra lá. Cachinhos Dourados está certo.
mikeserv

Respostas:

10

Este:

if [[ "$OPTARG" -eq 0 ]] 

Corresponderá a qualquer string, a menos que sejam apenas dígitos. Usar:

if [[ "$OPTARG" == "0" ]] 

Em vez de.

Cachinhos Dourados
fonte
8

Embora o problema em seu código tenha sido bem explicado por goldilocks , não resisto a dizer que seu código é desnecessariamente longo. Você poderia simplificá-lo muito.

O seguinte é equivalente ao código desejado:

echo User passed in $1
if [[ "$1" == [nN0]* ]]; then      # First argument starts with either n, N, or 0
    echo Decline
elif [[ "$1" == [yY1]* ]]; then    # First argument starts with either y, Y, or 1
    echo Accept
else
    echo Invalid argument
fi

Você também pode querer consultar Construções Condicionais no manual .

devnull
fonte
Obrigado, devnull. Definitivamente vou usar esse truque em scripts futuros! Fiquei surpreso quanto a aceitar sua resposta, mas acho que as distinções na resposta dos goldilocks podem ser úteis para os outros.
21414 #
@i_grok Eu mencionei na minha resposta que a resposta dos goldilocks aponta para o problema. Eu simplesmente apresentei uma abordagem alternativa que parecia mais legível . É bom ver várias abordagens para resolver um problema surgir. Quanto à resposta aceita, é um assunto relativamente trivial.
devnull
6

Você também pode usar case

read -p 'Do you want to Continue (yes/no?): ' 
case $REPLY in
       [yY]|[yY][eE][sS]) echo Accept             ;;
           [nN]|[nN][oO]) echo Decline            ;;
                       *) echo "Invalid argument" ;;
esac
Rahul Patil
fonte