Bash oder Bedingung in einer While-Anweisung

Bash oder Bedingung in einer While-Anweisung

Ich möchte ein Skript in Bash schreiben, das die Benutzereingabe überprüft, ob sie gleich "stringA" oder "stringB" ist und falls sie gleich einer dieser Zeichenfolgen ist, soll es die Benutzereingabe drucken. Mein Code ist:

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

Leider funktioniert dieser Code nicht und läuft endlos. Ich kann nur vergleichen, ob das $resultgleich einem der Strings ist, indem ich das ||und den zweiten Teil der while-Schleife entferne. Ich habe versucht, das ||durch zu ersetzen -o, aber ich habe den folgenden Fehler erhalten:

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

Antwort1

Das liegt daran, dass Sie verwenden möchten &&und nicht ||.

Sie möchten die Schleife wiederholen, wenn das Ergebnis weder stringA noch stringB ist. Kein String kann beiden gleich sein, da dies Ihre Schleife beenden würde.

Sie können ein Muster auch in Folgendem verwenden [[ ... ]]:

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

Antwort2

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

In der Textsprache, während weder das Ergebnis Stringa noch das Ergebnis Stringb ist, tun Sie...

Achten Sie auf "die Umgebung Ihrer Variablen, sonst erhalten Sie eine Fehlermeldung, wenn die Variable $resultleer ist.

Antwort3

Das Problem in Ihrem Code ist, dass Ihre Schleife wiederholt wird, während dies $resultnicht dasselbe ist wiebeide stringAund stringB(gleichzeitig). Sie können verwenden

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

oder

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

Damit ein Benutzer eine von mehreren Optionen auswählt, sollten Sie ihn nicht dazu bringen, lange Zeichenfolgen einzugeben. Stellen Sie ihm stattdessen ein einfaches Menü zur Auswahl zur Verfügung.

Anregung:

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

Folgendes ausführen:

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

Antwort4

Eine shVariante, die die Probleme beseitigen würde, ${var,,}die damit verbunden sind, dass zum Konvertieren von Zeichenfolgen das Gebietsschema verwendet wird (Kleinbuchstaben Isind ibeispielsweise nicht jedermanns Sache):

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

verwandte Informationen