Przetwarzanie odpowiedzi Tak / Nie od użytkownika Bash

11

To bardzo dobrze może być z mojej strony głupota. Chciałbym zaakceptować odpowiedzi Tak / Nie, Prawda / Fałsz w moim skrypcie 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

Oto kilka przykładowych wyników:

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

User passed in No
Decline

Teraz stumper. Dlaczego [[ "${OPTARG^^}" == "N" ]]zwracanie wartości true dla dowolnego ciągu !?

./test.sh Tak

User passed in Yes
Decline

./test.sh ThisShouldNotMatch

User passed in ThisShouldNotMatch
Decline
i_grok
źródło
co się stanie, jeśli to zacytujesz? OPTARG = „$ {ARGUMENT: 0: 1}”
mikeserv
1
Nieważne. Złotowłosa ma rację.
mikeserv

Odpowiedzi:

10

To:

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

Dopasuje dowolny ciąg, chyba że są to tylko cyfry. Posługiwać się:

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

Zamiast.

Złotowłosa
źródło
8

Chociaż problem w twoim kodzie został dobrze wyjaśniony przez goldilocks , nie mogę się oprzeć stwierdzeniu, że twój kod jest niepotrzebnie długi. Możesz to bardzo uprościć.

Poniższy kod odpowiada żądanemu kodowi:

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

Możesz także zapoznać się z Konstrukcjami warunkowymi w instrukcji .

diabelnie
źródło
Dziękuję Devnull. Z pewnością skorzystam z tej sztuczki w przyszłych skryptach! Byłem rozdarty, czy powinienem przyjąć twoją odpowiedź, ale myślę, że rozróżnienia w odpowiedzi złocistych mogą być pomocne dla innych.
i_grok
@ i_grok W swojej odpowiedzi wspomniałem, że odpowiedź goldilocks wskazuje na problem. Po prostu przedstawiłem alternatywne podejście, które wydawało się bardziej czytelne . Dobrze jest widzieć wiele podejść do rozwiązania problemu. Ustalenie, która odpowiedź jest akceptowana, jest stosunkowo trywialną sprawą.
devnull
6

Możesz także użyć 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
źródło