wiki:Shell

Version 4 (modified by atzm, 17 years ago) (diff)

--

Shell

シェルプログラミングはどこかに落とし穴がありそうで怖い.

依存性を持つ関数呼び出し

  • dep.sh
    function die ()
    {
      local stat=$1
      local msg=$2
    
      echo "${msg} (S:${stat})" 1>&2
      exit ${stat}
    }
    
    function _depnum ()
    {
      local tgt=$1
    
      for ((i=${#CHAIN[@]}; i >= 0; i--)); do
        if [ "x${tgt}" = "x${CHAIN[$i]}" ]; then
          echo $i
          exit 0
        fi
      done
    }
    
    function run ()
    {
      if [ -z "$CHAIN" ]; then
        die 30 "\`\$CHAIN' not declared"
      fi
    
      local tgt=$1
      local arg=$2
      local dnum=`_depnum ${tgt}`
    
      if [ -z "${dnum}" ]; then
        die 36 "ERR: no such target: ${tgt}"
      fi
    
      for ((i=0; i <= ${dnum}; i++)); do
        arg="`${CHAIN[$i]} ${arg}`"
      done
    
      if [ -n "${arg}" ]; then
        echo ${arg}
      fi
    }
    
  • dop.sh
    #!/bin/sh
    
    source dep.sh
    
    function clean ()
    {
      echo "arg_clean:  $1" 1>&2
      echo "cleaned"
    }
    
    function pack ()
    {
      echo "arg_pack:   $1" 1>&2
      echo "packed"
    }
    
    function upload () 
    {
      echo "arg_upload: $1" 1>&2
      echo "uploaded"
    }
    
    CHAIN=(clean pack upload)
    
    if [ $# -eq 1 ]; then
      res=`run $1 init`
      echo
      echo "result: ${res}"
    else
      die 24 "syntax error"
    fi
    
  • 実行結果
    $ sh ./dop.sh clean
    arg_clean:  init
    
    result: cleaned
    
    $ sh ./dop.sh pack
    arg_clean:  init
    arg_pack:   cleaned
    
    result: packed
    
    $ sh ./dop.sh upload
    arg_clean:  init
    arg_pack:   cleaned
    arg_upload: packed
    
    result: uploaded
    

適当な説明

  • $CHAIN に関数名のチェーンを定義します
  • run() の第 1 引数が最終的に呼びたい関数名です
  • run() の第 2 引数はチェーンの一番最初の関数の引数として渡されます
  • 前の関数の標準出力が次の関数の引数にセットされます
  • デバッグ目的などで各関数内で標準出力に何かを吐くとおかしなことになるので標準エラー出力を使いましょう (書いてる時自分ではまりました)