14903


シェル初心者です。  
↓の本を参考に勉強をしていたのですが、caseの評価で気になるところが出てきたので  
質問させてください。コードも↓の本から抜粋しています。  
[技術評論社 -
［改訂新版］シェルスクリプト基本リファレンス](http://gihyo.jp/magazine/wdpress/plus/978-4-7741-4643-0)  

[code]

    case `uname -s` in
     Linux)
     echo 'OSはLinuxです'
     ;;
     FreeBSD)
     echo 'OSはFreeBSDです'
     ;; 
     Solaris)
     echo 'OSはSolarisです'
     ;; 
     *) 
     echo 'その他のOSです'
     ;;
    esac 
    
[/code]

という処理なのですが、

[code]

    uname -s
    
[/code]

というコマンドはパターンが実行されるたびに実行される認識は正しいでしょうか？  
重い処理をcase文の文字列に入れるとパフォーマンスが劣化してしまうのではないかと懸念しております。

また、比較はif文同様testコマンドで実行される認識はあってますでしょうか？

ご存知の方がいらっしゃいましたらお手数をおかけしますがご教授頂けると幸いです。  
よろしくお願いします。


CC BY-SA 3.0
2015-08-27T08:56:43.720
14900
2015-08-28T00:36:16.580
7918
question
bash sh shellscript
シェルスクリプトのcase文の評価について教えてください。


`uname -s` が実行されるのは一回だけです。

[code]

    $ strace -f sh -c 'case `uname -s` in x) ;; y) ;; esac' 2>&1|grep 'exec[^ ]*uname'
    [pid  4662] execve("/bin/uname", ["uname", "-s"], [/* 73 vars */]) = 0
    
[/code]

`test` コマンドは利用しません。シェルの内部コマンドとして実行されます。なお、私の知る限り、世の中の sh とその派生シェルの `test` コマンド
(`[` コマンド)もシェルの内部コマンドです。

また、`if` 文は必ず `test` コマンドが実行されるものではありません。`if`
の後に記述した任意のコマンドラインの終了コードで判定しているだけです。


CC BY-SA 3.0
2015-08-27T09:18:52.210
14901
2015-08-27T09:53:10.680
2015-08-27T09:53:10.680
3061
3061
14900
answer


  1. `case` は operand を１回だけ評価します。

  2. 各パターンを指定された順番に shell-glob 規則に基づいて operand と一致するかを試します。

  3. パターン一致時 `;;` に至ったら `esac` に行きます（終了です）

  4. パターン一致時 `;;&` に至ったら次のパターンをさらに評価しに行きます

ということで

[code]

    case abc in
    a*)
         echo match to a-asterisk
         ;;&
    b)
         echo match to b
         ;;
    abc)
         echo match to abc
         ;;
    esac
    
[/code]

は２つマッチします（どれにマッチするか考えてください）。  
マッチパターンは shell-glob であって regexp ではないため `^a*` とかしてもマッチしません。

っと。  
上記 `;;&` は最近の [bash](/questions/tagged/bash "'bash' のタグが付いた質問を表示") 拡張機能であって、古い
[bash](/questions/tagged/bash "'bash' のタグが付いた質問を表示") および
[sh](/questions/tagged/sh "'sh' のタグが付いた質問を表示") では使えません。


CC BY-SA 3.0
2015-08-27T09:26:32.590
14903
2015-08-28T00:36:16.580
2015-08-28T00:36:16.580
8589
8589
14900
answer