11

文字列を分割し、配列に入れて値を出力するサンプルのKornShell関数を作成しました。コードは以下の通りです

#!/usr/bin/ksh

splitString() {

    string="abc@hotmail.com;xyz@gmail.com;uvw@yahoo.com"

    oIFS="$IFS"; 
    IFS=';' 
    set -A str $string
    IFS="$oIFS"
}

splitString
echo "strings count = ${#str[@]}"
echo "first : ${str[0]}";
echo "second: ${str[1]}";
echo "third : ${str[2]}";

現在、echoは配列の値を出力しないため、定義された配列のスコープと関係があると思います。

私はシェルスクリプトを初めて使用しますが、上記の例の変数のスコープを理解するのを手伝ってくれる人はいますか?

4

2 に答える 2

17

変数のデフォルトのスコープはスクリプト全体です。

ただし、関数内で変数を宣言すると、変数はそれを宣言する関数に対してローカルになります。Ksh には動的スコープがあるため、変数は、変数を宣言する関数によって呼び出される関数でもアクセスできます。これは、マニュアルの関数に関するセクションで簡潔に文書化されています。AT&T ksh では (pdksh と派生物、および bash と zsh の同様の機能とは対照的に)、これはfunctionキーワードで定義された関数にのみ適用され、従来のf () { … }構文で定義された関数には適用されないことに注意してください。AT&T ksh93 では、従来の構文で定義された関数で宣言されたすべての変数はグローバルです。

変数を宣言する主な方法は、typeset ビルトインを使用することです。常に変数をローカルにします (AT&T ksh では、 で宣言された関数のみfunction)。で宣言せずに変数に割り当てると、typesetグローバルになります。

set -Aksh のドキュメントでは、変数をローカルにするかグローバルにするかは指定されておらず、バージョンが異なるといずれかになります。ksh 93u、pdksh、または mksh では、変数はグローバルであり、スクリプトは値を出力します。スコープがローカルである ksh88 または古いバージョンの ksh があるようです。関数の外で初期化するとグローバル変数が作成されると思いますstrが、よくわかりません。

ローカル変数を使用して の値をオーバーライドする必要があることに注意してください。別の変数への保存は扱いにくいだけでなく、設定されていない場合は適切にIFS復元されないため脆弱でもあります。IFSさらに、グロビングをオフにする必要があります。そうしないと、文字列にシェルのグロビング文字が含まれていて?*\[、その単語の 1 つがシステム上の 1 つまたは複数のファイルと一致する場合、それが展開されます。たとえばset -A $string、where stringisa;*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"
于 2012-08-17T10:28:55.083 に答える
3

変数は通常、変数が定義された時点から、変数が定義されているシェルに対してグローバルです。

コマンドは、typesetそれらが定義されている関数に対してローカルにするか、代わりにそれらを自動的にエクスポートすることができます (更新された場合でも)。

manpage または Korn の本で「typeset」と「integer」を読んでください。

于 2012-08-17T08:33:46.797 に答える