質問: シェル初心者です。 ↓の本を参考に勉強をしていたのですが、caseの評価で気になるところが出てきたので 質問させてください。コードも↓の本から抜粋しています。 技術評論社 - [改訂新版]シェルスクリプト基本リファレンス ``` case `uname -s` in Linux) echo 'OSはLinuxです' ;; FreeBSD) echo 'OSはFreeBSDです' ;; Solaris) echo 'OSはSolarisです' ;; *) echo 'その他のOSです' ;; esac ``` という処理なのですが、 ``` uname -s ``` というコマンドはパターンが実行されるたびに実行される認識は正しいでしょうか? 重い処理をcase文の文字列に入れるとパフォーマンスが劣化してしまうのではないかと懸念しております。 また、比較はif文同様testコマンドで実行される認識はあってますでしょうか? ご存知の方がいらっしゃいましたらお手数をおかけしますがご教授頂けると幸いです。 よろしくお願いします。
回答: 1. `case` は operand を1回だけ評価します。 2. 各パターンを指定された順番に shell-glob 規則に基づいて operand と一致するかを試します。 3. パターン一致時 `;;` に至ったら `esac` に行きます(終了です) 4. パターン一致時 `;;&` に至ったら次のパターンをさらに評価しに行きます ということで ``` case abc in a*) echo match to a-asterisk ;;& b) echo match to b ;; abc) echo match to abc ;; esac ``` は2つマッチします(どれにマッチするか考えてください)。 マッチパターンは shell-glob であって regexp ではないため `^a*` とかしてもマッチしません。 っと。 上記 `;;&` は最近の [bash](/questions/tagged/bash "'bash' のタグが付いた質問を表示") 拡張機能であって、古い [bash](/questions/tagged/bash "'bash' のタグが付いた質問を表示") および [sh](/questions/tagged/sh "'sh' のタグが付いた質問を表示") では使えません。