Variablenzuordnung außerhalb der case-Anweisung

8

In vielen Sprachen ist es möglich, das Ergebnis einer case / switch-Anweisung einer Variablen zuzuweisen, anstatt die Variablenzuweisung innerhalb der case-Anweisung viele Male zu wiederholen. Ist es möglich, so etwas in der Bash-Shell zu tun?

color_code=$(case "$COLOR" in
  (red)    1;;
  (yellow) 2;;
  (green)  3;;
  (blue)   4;;
esac)

(Oder nebenbei in anderen Muscheln?)

Bilderstürmer
quelle
Sie haben extra (s. Ansonsten ist es in Ordnung.
HalosGhost

Antworten:

6

Das variable=$(...)Konstrukt nimmt die Standardausgabe des Befehls $(...)und weist sie zu variable. Um variabledie gewünschte Zuordnung zu erhalten , müssen die Werte an die Standardausgabe gesendet werden. Dies ist einfach mit dem echoBefehl zu tun :

color_code=$(case "$COLOR" in
  red)    echo 1;;
  yellow) echo 2;;
  green)  echo 3;;
  blue)   echo 4;;
esac)

Dies funktioniert bashgenauso wie alle anderen POSIX-Shells.

Die optionalen linken Parens

Gemäß dem POSIX-Standard sind die linken Parens in einer caseAnweisung optional und Folgendes funktioniert ebenfalls:

color_code=$(case "$COLOR" in
  (red)    echo 1;;
  (yellow) echo 2;;
  (green)  echo 3;;
  (blue)   echo 4;;
esac)

Wie Gilles in den Kommentaren hervorhebt, akzeptieren nicht alle Shells beide Formen in Kombination mit $(...): Eine beeindruckend detaillierte Tabelle der Kompatibilität finden Sie unter "$ ()" Befehlssubstitution vs. eingebettet ")" .

John1024
quelle
Auf einer Seite, die ich überprüft habe (ich erinnere mich nicht, wo sie war), wurde die Öffnung (als optional aufgeführt. Ich dachte, es könnte helfen, zu vermeiden, dass das )als Abschluss )für den $(...)Ausdruck falsch interpretiert wird .
Bilderstürmer
@iconoclast Ja. Die Öffnung (ist optional: Der Code funktioniert ohne oder ohne sie gleich. Ich habe sie nur deshalb weggelassen, weil das Tradition ist. Der Hauptteil der vorgeschlagenen Lösung ist die Verwendung von echo.
John1024
1
@iconoclast Ältere Shells (vor POSIX) erlaubten kein Öffnen (für caseMuster, aber einige Shells haben das Öffnen zugelassen und erforderten das Öffnen, (wenn casees in einer Befehlssubstitution verwendet wird. Moderne Muscheln sind in beiden Fällen in Ordnung. Siehe inulm.de/~mascheck/various/cmd-subst
Gilles 'SO- hör auf böse zu sein'
1
@ Gilles Danke für diese Info. Die Tiefe Ihres Wissens ist wie immer beeindruckend.
John1024
2

color_code=$(…)Weist die Ausgabe des Befehls der Variablen zu color_code, wobei die letzten Zeilenumbrüche entfernt werden. Sie müssen also eine Ausgabe produzieren. Der von Ihnen geschriebene Code versucht, 1als Befehl ausgeführt zu werden.

Sie können diese Redewendung verwenden. Beachten Sie, dass color_codedies leer ist, wenn $COLORkeiner der unterstützten Werte vorhanden ist.

color_code=$(case "$COLOR" in
  (red)    echo 1;;
  (yellow) echo 2;;
  (green)  echo 3;;
  (blue)   echo 4;;
esac)

Aber es ist nicht sehr idiomatisch. Die Shell-Sprache ist auf einfache Kombinationen einfacher Befehle ausgerichtet. Diese große Befehlsersetzung ist umständlich. Durch die Befehlssubstitution wird eine Unterschale erstellt, die langsamer ist als die einfache Methode:

case "$COLOR" in
  red)    color_code=1;;
  yellow) color_code=2;;
  green)  color_code=3;;
  blue)   color_code=4;;
esac

Der semantische Hauptunterschied zwischen den beiden Ansätzen besteht darin, dass $(…)eine Unterschale erstellt wird, sodass jede Zuweisung, Beendigung, Umleitung usw., die innerhalb ausgeführt wird, keine Auswirkung außerhalb hat.

Gilles 'SO - hör auf böse zu sein'
quelle