変数のデフォルトスコープはスクリプト全体です。
しかし、関数内で変数を宣言すると、その変数は宣言している関数に対してローカルになります。 Kshはdynamic scopingなので、変数を宣言する関数によって呼び出される関数で変数にアクセスすることもできます。これはsection on functions in the manualに簡潔に記載されています。 AT & Tksh(pdkshと派生語、およびbashとzshの類似の機能とは対照的)では、これはfunction
キーワードで定義された関数にのみ適用され、従来のf() { … }
構文で定義された関数には適用されません。 AT & T ksh93では、従来の構文で定義された関数で宣言されたすべての変数はグローバルです。
変数を宣言する主な方法は、typeset
builtinです。それは常にローカル変数を作成します(AT & T ksh、function
で宣言された関数のみ)。 typeset
で宣言していない変数に代入すると、グローバルになります。
kshのドキュメントでは、set -A
がローカル変数またはグローバル変数を作成するかどうかは指定されておらず、異なるバージョンでもどちらかが作成されます。 ksh 93u、pdkshまたはmkshでは、変数はグローバルであり、スクリプトは値を出力します。スコープがローカルのksh88または古いバージョンのkshがあるようです。関数の外にstr
を初期化するとグローバル変数が作成されると思いますが、わかりません。
IFS
の値を上書きするには、ローカル変数を使用する必要があります。別の変数への保存は不器用であるだけでなく、設定されていなければIFS
を適切に復元しないため脆弱です。さらに、文字列にシェルグロブ文字?*\[
が含まれていて、その単語の1つがシステム上の1つ以上のファイルと一致すると、globbingがオフになるはずです。 set -A $string
がa;*
の場合、現在のディレクトリにファイル名のリストを含むstr
になります。
set -A str
function splitString {
typeset IFS=';' globbing=1
case $- in *f*) globbing=;; esac
set -f
set -A str $string
if [ -n "$globbing" ]; then set +f; fi
}
splitString "$string"
Gotcha !!!! スクリプトは動作していますが、問題はありません。関数を間違った方法で呼び出すという小さな誤りがあった。 しかし、まだKSHの変数の範囲を理解したいと思うでしょう – Vivek