私はtypeset
それが失敗ksh
すると思いましたが、他のすべてのサポートシェル(bash、yash、zsh、pdksh)では動作しますが、local
これは失敗します。ksh93
typeset
#!/bin/ksh -ex
foo(){
typeset a b
a=0; b=1
return
}
a=a; b=b
foo
#confirm that the globals didn't change
[ "$a" = a ]
[ "$b" = b ]
何を提供しますか?
ベストアンサー1
typeset
ksh93用です(private
動的スコープの代わりにsなどの静的スコープを使用)。 ksh関数定義スタイルを使用して宣言された関数に対してのみ機能します。perl
my
local
function foo {
typeset var=whatever
...
}
Bourne構文を使用すると(または.
kshスタイル関数でも機能するコマンドを使用すると)、範囲はありません(もちろん、$1
...$2
を除く$#
)。したがって、Bourneスタイル関数を使用して親コンテキストから値を取得したり、変数の値または型を変更したりできます(typeset -n
kshスタイルでも使用できます)。
ksh88 では、ダイナミックスコープにtypeset
ksh および Bourne 関数定義スタイルを使用します。 David Kornによると、POSIXはkshの変数の範囲を指定しません。動的(劣ったと見なされる)それで彼は静的範囲ksh93
(完全な書き換え)に変更しました。
しかし、同時に他のシェルも変数スコープを実装し、すべてを使用しました。動的範囲はksh88を模倣します。
zsh
これで、inに似た動的範囲を持つ/に加えて、private
sに似た範囲を持つキーワードがあります。ksh93
local
typeset
ksh88
静的範囲と動的範囲の違いを確認するには、以下を比較します。
"$shell" -c 'function f { typeset a=1; g; echo "$a"; }
function g { echo "$a"; a=2; }
a=0; f'
ここで$shell
==ksh93
出力:
0
1
そして、以下を使用またはksh88
出力bash
します。
1
2
zsh
:
$ zsh -c 'zmodload zsh/param/private
f() { private a=1; g; echo $a;}
g() { echo $a; a=2; }
a=0; f'
0
1
bash
、、、または/ shに移植可能なコードでローカルスコープを使用するには、次のようにしますzsh
。ksh88
ksh93
pdksh
yash
dash
FreeBSD
[ -n "$BASH_VERSION" ] && shopt -s expand_aliases
alias shdef= kshdef='#'
if type typeset > /dev/null 2>&1; then
alias mylocal=typeset
if (a=1; f() { typeset a=2; }; f; [ "$a" = 2 ]); then
alias shdef='#' kshdef='function'
fi
else
alias mylocal=local
fi
次に、関数を次のように宣言します。
kshdef foo
shdef foo()
{
mylocal var
var=value
...
}
それにもかかわらず、local
異なるシェルの動作には多くの違いがあります。上記の動的および静的考慮事項に加えて、変数が最初に設定されていなかった値またはnull値を取得するのか、または親範囲からその値を継承するのかがあります。 /がキーワードか組み込みか(split + glob処理に影響を与える)とのreadonly
やり取りもあります...unset
local
typeset
kshスタイル関数定義の使用には異なる意味がありますksh93
。詳しくはマニュアルページをご覧ください。
もっと読む
- http://austingroupbugs.net/view.php?id=767標準化のためにPOSIXをお勧めします
sh
。 - シェルリストはローカル変数を定義するために `local`キーワードをサポートしています。