[[PageOutline]] = Shell = シェルプログラミングはどこかに落とし穴がありそうで怖い. == 依存性を持つ関数呼び出し == * {{{dep.sh}}} {{{ #!sh #!/bin/sh function die () { local stat=$1 local msg=$2 echo "${msg}: ${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 die 15 "ERR: no such target: ${tgt}" } function run () { if [ -z "$CHAIN" ]; then die 33 "\`\$CHAIN' not declared" fi local tgt=$1 local arg=$2 local dnum=`_depnum ${tgt}` for ((i=0; i <= ${dnum}; i++)); do arg="`${CHAIN[$i]} ${arg}`" done if [ -n "${arg}" ]; then echo ${arg} fi } }}} * {{{dop.sh}}} {{{ #!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 $ sh dop.sh upload arg_clean: init arg_pack: cleaned arg_upload: packed result: uploaded $ sh dop.sh pack arg_clean: init arg_pack: cleaned result: packed $ sh dop.sh clean arg_clean: init result: cleaned }}} === 適当な説明 === * run() の第 1 引数が最終的に呼びたい関数名です * run() の第 2 引数はチェーンの一番最初の関数の引数として渡されます * 前の関数の標準出力が次の関数の引数にセットされます * デバッグ目的などで各関数内で標準出力に何かを吐くとおかしなことになるので標準エラー出力を使いましょう (書いてる時自分ではまりました)