Case ステートメント外の変数の代入

Case ステートメント外の変数の代入

多くの言語では、Caseステートメント内で変数の割り当てを複数回繰り返すのではなく、Case / Switchステートメントの結果を変数に割り当てることができます。 Bashシェルでも同様のことができますか?

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

(または他のシェルから?)

答え1

このvariable=$(...)設定は、すべてのコマンドの標準出力を取得し$(...)て割り当てますvariable。したがって、variable必要な方法で割り当てるには、その値を標準出力に送信する必要があります。これは、次のコマンドを使用して簡単に実行できますecho

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

bashこれは他のすべてのPOSIXシェルで機能します。

オプションの左括弧

POSIX 標準によれば、caseステートメントの開き括弧はオプションであり、以下も適用されます。

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

Gillesがコメントで指摘したように、すべてのシェルが$(...)これら2つの形式の組み合わせを許可するわけではありません。印象的に詳細な互換性表を参照してください。"$( )" コマンドを含む ")" に置き換え

答え2

color_code=$(…)コマンドの出力を変数に割り当てcolor_code、最後の改行文字を削除します。したがって、いくつかの出力を生成する必要があります。作成したコードは1コマンドで実行しようとします。

このイディオムを使用できます。サポートされている値がない場合はcolor_code空です。$COLOR

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

しかし、これはあまり寛容ではありません。シェル言語は、単純なコマンドの簡単な組み合わせを指します。この種の大規模なコマンド置換は厄介です。コマンド置換は、直接メソッドよりも遅いサブシェルを生成します。

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

2つの方法の主な意味上の違いは、$(…)サブシェルが作成されるため、内部で実行されるすべての割り当て、終了、リダイレクトなどが外部に影響を与えないことです。

関連情報