[[PageOutline]] = Shell = シェルプログラミングはどこかに落とし穴がありそうで怖い. == 依存性を持つ関数呼び出し == * {{{dep.sh}}} {{{ #!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}}} {{{ #!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 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 引数はチェーンの一番最初の関数の引数として渡されます * 前の関数の標準出力が次の関数の引数にセットされます * デバッグ目的などで各関数内で標準出力に何かを吐くとおかしなことになるので標準エラー出力を使いましょう (書いてる時自分ではまりました)