Es sieht aus wie ein Fehler in Ihrem Code, aber wir können ihn sehr klein umgestalten ...
Wenn Sie Ihren Ausdruck wirklich mit geschrieben hätten [ foo = bar -o foo = car -o foo = jar -o foo = foo ]
, hätte er vereinfacht werden können zu:
echo yes
Dieser Test ist immer wahr, weil er foo = foo
immer wahr ist, was wiederum darauf zurückzuführen ist, dass die Literalzeichenfolge foo
immer dieselbe ist wie sie selbst.
Obwohl Sie klargestellt haben, dass diese Syntax nicht in dem Code enthalten ist, den Sie wirklich verwendet haben, habe ich diesen einleitenden Abschnitt beibehalten, da dies ein häufiger Fehler ist, insbesondere bei Anfängern. Der Versuch, den Wert auf foo
diese Weise zu überprüfen, funktioniert in keiner Bourne-Shell - um den Wert einer Variablen mit zu untersuchen [
, müssen Sie eine Parametererweiterung mit durchführen $
(siehe unten). Dieser spezielle Aspekt des Problems ist nicht Shell-spezifisch. Hier ist zum Beispiel ein Test in 7 Bourne-Muscheln .
Korrigieren des Originalcodes
Vielleicht wollten Sie stattdessen den Wert der foo
Variablen (dh ihren Inhalt und nicht ihren Namen) anhand dieser Zeichenfolgen überprüfen . In diesem Fall würde Ihr ursprünglicher Code wie folgt aussehen:
if [ "$foo" = bar -o "$foo" = car -o "$foo" = jar -o "$foo" = foo ]; then
echo yes
fi
Dies kann mit dem Kurzschlussbediener leicht verkürzt &&
werden:
[ "$foo" = bar -o "$foo" = car -o "$foo" = jar -o "$foo" = foo ] && echo yes
Aber es ist immer noch länger und komplizierter und wiederholt sich, als Sie wahrscheinlich bevorzugen. Also weiter ...
Kürzere Formulare über Pattern Matching
Sie können den in der [[
Einrichtung integrierten Operator für den Abgleich regulärer Ausdrücke verwenden:
[[ $foo =~ ^(bar|car|jar|foo)$ ]] && echo yes
Während die Verwendung case
wahrscheinlich der häufigste Weg ist, ist [[
mit =~
:
- die gleiche Länge wie eine kompakte Verwendung von
case
(siehe unten)
- Wahrscheinlich wahrer als die Logik Ihres ursprünglichen Codes, indem er verwendet
[[
, der ähnlich wie ein Testausdruck funktioniert.
Vielleicht bevorzugen Sie das also. Es ist die Methode, die ich wahrscheinlich verwenden würde, um dies in Bash zu tun.
Wenn Sie so etwas tun wollten, aber mit grep
statt [[
mit übereinstimmen =~
, ist dies ähnlich:
grep -Eq '^(bar|car|jar|foo)$' <<< "$foo" && echo yes
Oder dieses:
grep -Fqe{bar,car,jar,foo} <<< "$foo" && echo yes
Ein Einzeiler mit case
Wie Serg sagt , kann unter Verwendung vereinfacht werden case
statt if
und [
. Das ist der klassische und wahrscheinlich häufigste Weg.
Die Methode in Sergs Antwort funktioniert einwandfrei, aber für den bestimmten Code, den Sie umgestalten, können wir etwas Einfacheres schreiben, indem wir nur ein Muster für verwenden case
. Am Ende muss kein Allround- *)
Match stattfinden. Wenn die Zeichenfolge keinem der Muster entspricht, durchläuft die Steuerung einfach das case-Konstrukt und es werden keine Befehle ausgeführt, was Ihrem if
Konstrukt mit no entspricht else
.
case $foo in bar|car|jar|foo) echo yes;; esac
Das macht es kurz und einfach genug, um leicht in eine einzelne Zeile zu passen - und lesbar zu sein (was genau das zu sein scheint, wonach Sie suchen). Diese Methode kann auch auf andere Bourne-Shells als Bash übertragen werden.