シェルで定義した関数では、一般的なコンピュータ言語の概念に相当する戻り値を返すようにすることはできません。しかし、いくつかの方法で代替することができます。ここではその代替方法を紹介します。 |
終了ステータス
以下のような関数を定義した場合、この関数を実行した直後に「$?」とすれば、returnのあとに記述した「数値」を取得することができます。
roundSec() { # システム時刻の秒の値に応じて0か30を返す # 00~29秒:0 # 30~59秒:30 if [ `date '+%S'` -lt 30 ]; then return 0 else return 30 fi } roundSec echo $?
ただしここで設定することができるのは、0~255までの整数に限定されます。これはreturnで返せるのは「終了ステータス(exit-status)」であるからです。returnに文字列を設定した場合にはエラーになり、範囲外の数値を設定した場合には256で割った余りを返します(256は0、511は255、-1は255)。
また、関数の終了後に他のコマンドを実行してしまうと、そのコマンドの終了ステータスが設定されてしまいます。終了ステータスを取得する必要がある場合には、関数の終了直後に取得するようにしてください。
コマンドの終了ステータスとしては一般的には0が成功、1が失敗となっているものが多いためそれに準じることが望ましいと思いますが、
終了ステータスを利用すれば、実行結果の状態を256種類まで区別して伝えることができます。
標準出力の受け取り
標準出力に値を出力する関数を作り、その関数を以下のように呼び出すことにより、結果を変数に設定することができます。
変数名=`関数名`
もしくは
変数名=$(関数名)
roundSec() { # システム時刻の秒の値に応じて0か30を返す # 00~29秒:0 # 30~59秒:30 if [ `date '+%S'` -lt 30 ]; then echo "00秒" else echo "30秒" fi } RESULT=`roundSec` echo ${RESULT}
この方法は以下の制約があります。
- 関数内で標準出力した内容はすべて変数に設定される
- 関数から画面への標準出力ができなくなる
※私はこの方法を使ってsqlplusの実行結果を受け取るスクリプトをよく書きます。
グローバル変数を介した受渡し
単純に関数内からグローバル変数を変更する方法です。
roundSec() { # システム時刻の秒の値に応じて0か30を返す # 00~29秒:0 # 30~59秒:30 if [ `date '+%S'` -lt 30 ]; then SEC_VAL="00秒" else SEC_VAL="30秒" fi } roundSec echo ${SEC_VAL}
個別の関数でグローバル変数を書き換えるという点がイケていませんが、利用しやすい方法かと思います。
2011/07/26