Bashのビルトインコマンド”declare”の使い方紹介(変数の global スコープ/参照渡し)
またまた以下の内容の続きです。
まだまだ書き足りないけど今回で小休止を入れたいと思います。
- シェルスクリプトサンプルコードでよく見かける typeset や declare ってなに? | ゲンゾウ用ポストイット
- Bash のビルトインコマンド "declare" の使い方紹介(その1) | ゲンゾウ用ポストイット
- Bash のビルトインコマンド "declare" の使い方紹介(その2:大文字小文字の自動変換) | ゲンゾウ用ポストイット
- Bash のビルトインコマンド "declare" の使い方紹介(その3:読み取り専用) | ゲンゾウ用ポストイット
- Bash のビルトインコマンド "declare" の使い方紹介(変数の local スコープ) | ゲンゾウ用ポストイット
前回 関数内で declare
コマンドを使って定義した変数は、自動的に local スコープになるというところで終わりました。
では、関数内の local スコープ変数をもっと広いスコープにするにはどうしたらよいでしょう?
Contents
-g
オプション
declare
コマンドのオプションに -g
と言うものがあります。
デフォルトの local
スコープよりさらに広い global
スコープを設定してやることができます。
関数の内部で定義した変数を関数の外部でも利用できるようになります。
# 関数を定義
f () {
# -gオプションを付与して、globalスコープとする
declare -g -i N=4
echo "f: N=$N"
}
# 関数呼び出し前なので空
$ echo "N=$N"
N=
# 関数呼び出し。関数内の変数は当然見れる
$ f
f: N=4
# 関数呼び出し後はglobal変数が関数の外からも見れる
$ echo "N=$N"
N=4
# 変数を表示するだけの関数を作成
$ show_var () {
echo "show_var : N=$N"
}
# 表示させてみる
$ show_var
show_var : N=4
# 再度定義し直したらどうなるの?
$ f2 () {
declare -g -i N=5
echo "f2: N=$N"
}
# 上書きできちゃう
$ f2
f2: N=5
関数の外で参照できるだけでなく、他の関数からも参照できるようになります。
けれども、あんまり広いスコープの変数を使うことはないと思います。
ちなみに、 global 変数と local 変数は干渉し合わないのでしょうか?
# global変数を定義する関数
$ func_global () {
declare -g X=dog
echo "$X"
}
# 呼び出し
$ func_global
dog
# global変数を表示
$ echo "$X"
dog
# local変数を定義する関数
$ func_local () {
declare X=cat
echo "$X"
}
# 呼び出し前
$ echo "$X"
dog
# 呼び出し。関数内のX変数の値はたしかに変わっている
$ func_local
cat
# X変数の値は元に戻っている
$ echo "$X"
dog
同名の変数の干渉を避けることができます。
-n
オプション
呼び出し元に結果を返す方法として global 変数を使う方法があるが、ちょっと変わった方法もあります。
-n
オプションを使って変数の 参照渡し をする方法です。
# 関数呼び出し時の第一引数の参照をXという変数で定義
mod_var () {
declare -n X="$1"
# 値を書き換えちゃう
X=100
echo "mod_var: $X"
}
# 変数を定義
declare Y=50
# 確認
$ echo "$Y"
50
# 関数呼び出し。値を書き換えてほしい変数を渡す
$ mod_var Y
mod_var: 100
# 変数の値を確認
$ echo "$Y"
100
# 関数内部で定義した変数Xはlocalスコープなので当然見えない
$ echo "$X"
-n
オプションは値を書き換えるときだけでなく、 連想配列 や 配列 として定義した変数を関数に引き渡す際に使います。
$ show_array () {
declare -n ARRAY="$1"
echo "-----"
echo "${ARRAY[@]}"
echo "-----"
}
$ declare -a N=(1 2 3 4 5)
# 関数の外では当然見れる
$ echo "${N[@]}"
1 2 3 4 5
# 関数の引数に配列を渡す
$ show_array N
-----
1 2 3 4 5
-----
$ show_hash () {
declare -n HASH="$1"
echo "-----"
echo "${HASH[b]}"
echo "-----"
}
$ declare -A N=([a]=x [b]=y [c]=z)
$ echo "${N[b]}"
y
$ show_hash N
-----
y
-----
ディスカッション
コメント一覧
まだ、コメントがありません