ksh93の組版が期待どおりに動作しません。

ksh93の組版が期待どおりに動作しません。

私はtypesetそれが失敗kshすると思いましたが、他のすべてのサポートシェル(bash、yash、zsh、pdksh)では動作しますが、localこれは失敗します。ksh93typeset

#!/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

typesetksh93用です(private動的スコープの代わりにsなどの静的スコープを使用)。 ksh関数定義スタイルを使用して宣言された関数に対してのみ機能します。perlmylocal

function foo {
  typeset var=whatever
  ...
}

Bourne構文を使用すると(または.kshスタイル関数でも機能するコマンドを使用すると)、範囲はありません(もちろん、$1...$2を除く$#)。したがって、Bourneスタイル関数を使用して親コンテキストから値を取得したり、変数の値または型を変更したりできます(typeset -nkshスタイルでも使用できます)。

ksh88 では、ダイナミックスコープにtypesetksh および Bourne 関数定義スタイルを使用します。 David Kornによると、POSIXはkshの変数の範囲を指定しません。動的(劣ったと見なされる)それで彼は静的範囲ksh93(完全な書き換え)に変更しました。

しかし、同時に他のシェルも変数スコープを実装し、すべてを使用しました。動的範囲はksh88を模倣します。

zshこれで、inに似た動的範囲を持つ/に加えて、privatesに似た範囲を持つキーワードがあります。ksh93localtypesetksh88

静的範囲と動的範囲の違いを確認するには、以下を比較します。

"$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に移植可能なコードでローカルスコープを使用するには、次のようにしますzshksh88 ksh93pdkshyashdashFreeBSD

[ -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やり取りもあります...unsetlocaltypeset

kshスタイル関数定義の使用には異なる意味がありますksh93。詳しくはマニュアルページをご覧ください。

もっと読む

おすすめ記事