2

ksh88 と ksh93 で実行される KornShell (ksh) スクリプトで問題が発生しました。この問題では、関数を呼び出す関数の処理が異なり、変数は typeset と export で宣言されます。違いを強調するスクリプトの例を次に示します。

#!/bin/ksh
# example.ksh: highlights differences between typeset and export on ksh93
function inner
{
  echo "  Inside inner, before assignment, TEST_VALUE=[$TEST_VALUE]"
  TEST_VALUE=abc
  echo "  Inside inner, after assignment, TEST_VALUE=[$TEST_VALUE]"
}
function outer_typeset
{
  typeset TEST_VALUE
  echo "Inside outer_typeset, before call of inner, TEST_VALUE=[$TEST_VALUE]"
  inner
  echo "Inside outer_typeset, after call of inner, TEST_VALUE=[$TEST_VALUE]"
}
function outer_typeset_x
{
  typeset -x TEST_VALUE
  echo "Inside outer_typeset_x, before call of inner, TEST_VALUE=[$TEST_VALUE]"
  inner
  echo "Inside outer_typeset_x, after call of inner, TEST_VALUE=[$TEST_VALUE]"
}
function outer_export
{
  export TEST_VALUE
  echo "Inside outer_export, before call of inner, TEST_VALUE=[$TEST_VALUE]"
  inner
  echo "Inside outer_export, after call of inner, TEST_VALUE=[$TEST_VALUE]"
}

outer_typeset
unset TEST_VALUE
echo
outer_typeset_x
unset TEST_VALUE
echo
outer_export

ksh93 を実行している Linux ボックスで実行した場合の結果は次のとおりです。

$ echo ${.sh.version}
Version M 1993-12-28 r

$ ./example.ksh
Inside outer_typeset, before call of inner, TEST_VALUE=[]
  Inside inner, before assignment, TEST_VALUE=[]
  Inside inner, after assignment, TEST_VALUE=[abc]
Inside outer_typeset, after call of inner, TEST_VALUE=[]

Inside outer_typeset_x, before call of inner, TEST_VALUE=[]
  Inside inner, before assignment, TEST_VALUE=[]
  Inside inner, after assignment, TEST_VALUE=[abc]
Inside outer_typeset_x, after call of inner, TEST_VALUE=[]

Inside outer_export, before call of inner, TEST_VALUE=[]
  Inside inner, before assignment, TEST_VALUE=[]
  Inside inner, after assignment, TEST_VALUE=[abc]
Inside outer_export, after call of inner, TEST_VALUE=[abc]

TEST_VALUE がタイプセットされるとわかるように、制御が外部関数に戻ると、内部で設定された TEST_VALUE の値が失われます。export によって TEST_VALUE が宣言されている場合、制御がアウターに戻ったときに、インナーに設定された値が保持されます。

外側の関数が内側の関数を呼び出すときに呼び出される新しいプロセスがないため、変数がサブ関数のスコープを維持するためにエクスポートを使用する必要がある理由がわかりません。また、typeset -x は typeset と同じように動作することに注意しましたが、typeset -x は export と同等であると予想していました。

ksh88 (AIX、Solaris、HP-UX)、pdksh (Linux)、または MKS ksh、typeset、typeset -x、および export を実行しているマシンでこのプログラムを実行すると、この例では同じように動作します。

今のところ、ksh88 で開発およびテストされた同様のコードを使用するプログラムに ksh93 での互換性を提供するために、typeset を export に変更しました。

おそらくこれはksh93の欠陥ですか?

4

2 に答える 2

1

ksh93のマニュアルには、次のように書かれていtypesetます。

関数名構文で定義された関数内で呼び出されると、変数vnameの新しいインスタンスが作成され、関数の完了時に変数の値と型が復元されます。

そしてこれについてexport

指定された名前は、後で実行されるコマンドの環境に自動的にエクスポートされるようにマークされています。

特に、関数内でエクスポートを使用しても何も復元されません。

これはtypeset、他の言語の「プロシージャローカル変数」によって提供される機能を提供することを目的としているようです。私はそれを設計上の欠陥とは呼びません。

于 2010-06-04T18:53:46.017 に答える
1

スクリプトには and への呼び出しがinnerありますinner_functionが、後者は定義されていません。これは質問の単なるタイプミスですか、それとも実際のスクリプトにもこのエラーがありますか?

出力に表示される動作は正しいです。

の定義をouter_typeset_xからfunction outer_typeset_x {に変更してみてくださいouter_typeset_x () {。出力が の場合と同じになることがわかりますouter_export

于 2010-06-04T19:48:54.853 に答える