Bash関数のローカル変数

Bash関数のローカル変数

Bash関数でローカル変数を設定するのは混乱しています。

使用しているようです

  local dgt
  local ltr
  local braces
  local da

おそらく使用するよりも安全です。

  local dgt ltr braces da

その変数がローカル変数として定義されていないか、値が設定されていないかどうかが心配です。このようなことが起こりますか?

例えば

local foo="$(mycmd)"

コマンドの終了状態は、ローカル変数によって生成された終了状態に上書きされます。

もしそうなら、正しいコードは

local foo
foo=$(mycmd)

答え1

ローカルに定義されていないか、値が設定されていません。このようなことが起こりますか?

ローカルコマンド自体が最初に構文的に正しい場合、そのコマンドも定義されます。ローカルコマンドは、ローカルコマンドが評価される前または後に発生する可能性のあるコマンド置換(サブシェルで実行される)の終了値には興味がありません。

$ f() { local x=$(false); declare -p x; }; f; declare -p x
declare -- x=""
bash: declare: x: not found

少なくともそのような意図です。ただし、バグのため、期待どおりに動作しない可能性があります。特に次のような場合にはさらにそうです。配列値の定義以前のバージョンのBashでは。したがって、時には定義と宣言を分離することが実際にはより良いかもしれません。

答え2

FWIW、いくつかの違いは次のとおりです。

$ bash -c 'f() { local a="$(exit 3)" b="$?"; echo "$b"; }; f'
3
$ bash -c 'f() { local a="$(exit 3)"; local b="$?"; echo "$b"; }; f'
0
$ bash -c 'f() { local a="$(exit 3)" á=x b="$?"; echo "$? $b"; }; f'
environment: line 0: local: `á=x': not a valid identifier
1 3
$ mksh -c 'a=0; f(){ local á; local a; a=1; }; f; echo "$a"'
mksh: typeset: á: is not an identifier
0
$ mksh -c 'a=0; f(){ local á a; a=1; }; f; echo "$a"'
mksh: typeset: á: is not an identifier
1

他の多くのシェルとは異なり、bashはlocal変数がより高い範囲で宣言されているように変数を宣言することを許可しません。readonlyそれでもlocal Ûnsupported¹ other_varfor、inと同様に、inでまだ宣言されているlocal readonly_var other_varことがわかりました。bashother_varlocal


1はlocal Ûnsupported実際には動作しますが、シングルバイトでエンコードされたロケールbashにのみ適用されます(およびこのように分類されます)。Ûisalpha()

関連情報