関数の内部で定義されたksh名前空間に問題があります。

関数の内部で定義されたksh名前空間に問題があります。

私はここで初めてですksh。私が見る問題は、名前空間を定義すると~へ関数とその名前空間内で定義された変数は、名前空間の外側にある同じ名前の変数を削除します。また名前空間変数を作成します。しかし、名前空間を定義すると外部期待どおりに機能する関数です。

私は(強制)使用を主張

# ksh --version
  version         sh (AT&T Research) 93u+ 2012-08-01

次のスクリプト(testnamespace.sh)は問題を示しています。

#!/usr/bin/env ksh

function myfunc1 {
  echo Original
}

function myfunc2 {
  echo Original
}


function mytest {
  echo ""
  echo "In function, before namespace x"
  othervar=1
  echo "        myvar = $myvar (expected value: 1)"
  echo "     othervar = $othervar (expected value: 1)"
  echo "      myfunc1 : $(myfunc1) (expected output: Original)"
  namespace x {
    echo ""
    echo "In namespace x defined inside function"
    echo "        myvar = $myvar (expected value: 1)"
    echo "     othervar = $othervar (expected value: 1)"
    echo "      myfunc1 : $(myfunc1) (expected output: Original)"
    myvar=2
    othervar=2    
    function myfunc1 {
      echo Modified
    }
    echo ""
    echo "        myvar = $myvar (expected value: 2)"
    echo "     othervar = $othervar (expected value: 2)"
    echo "      myfunc1 : $(myfunc1) (expected output: Modified)"
  }
  echo ""
  echo "In function, after namespace x"
  echo "        myvar = $myvar (expected value: 1)"
  echo "     othervar = $othervar (expected value: 1)"
  echo "      myfunc1 : $(myfunc1) (expected output: Original)"
  echo "     .x.myvar = ${.x.myvar} (expected value: 2)"
  echo "  .x.othervar = ${.x.othervar} (expected value: 2)"
  echo "   .x.myfunc1 : $(.x.myfunc1) (expected output: Modified)"
}

myvar=1
echo ""
echo "Before function"
echo "        myvar = $myvar (expected value: 1)"
echo "      myfunc1 : $(myfunc1) (expected output: Original)"

mytest

echo ""
echo "After function"
echo "        myvar = $myvar (expected value: 1)"
echo "      myfunc1 : $(myfunc1) (expected output: Original)"

thisvar=1
echo ""
echo "Before namespace y"
echo "      thisvar = $thisvar"
echo "      myfunc2 : $(myfunc2) (expected output: Original)"
namespace y {
  echo ""
  echo "In namesapce y"
  echo "      thisvar = $thisvar (expected value: 1)"
  echo "      myfunc2 : $(myfunc2) (expected output: Original)"
  thisvar=2
  function myfunc2 {
    echo Modified
  }
  echo ""
  echo "      thisvar = $thisvar (expected value: 2)"
  echo "      myfunc2 : $(myfunc2) (expected output: Modified)"
}
echo ""
echo "Outside namespace y"
echo "      thisvar = $thisvar (expected value: 1)"
echo "      myfunc2 : $(myfunc2) (expected output: Original)"
echo "   .y.thisvar = ${.y.thisvar} (expected value: 2)"
echo "   .y.myfunc2 : $(.y.myfunc2) (expected output: Modified)"
echo ""

実行時に少し注釈付きの出力testnamespace.sh

# ./testnamepace.sh

Before function
        myvar = 1 (expected value: 1)
      myfunc1 : Original (expected output: Original)

In function, before namespace x
        myvar = 1 (expected value: 1)
     othervar = 1 (expected value: 1)
      myfunc1 : Original (expected output: Original)

In namespace x defined inside function
        myvar = 1 (expected value: 1)
     othervar = 1 (expected value: 1)
      myfunc1 : Original (expected output: Original)

        myvar = 2 (expected value: 2)
     othervar = 2 (expected value: 2)
      myfunc1 : Modified (expected output: Modified)

In function, after namespace x
        myvar = 2 (expected value: 1)                <<--- Why are these
     othervar = 2 (expected value: 1)                <<--- both clobbered?
      myfunc1 : Original (expected output: Original) <<--- But this is OK!
     .x.myvar = 2 (expected value: 2)
  .x.othervar = 2 (expected value: 2)
   .x.myfunc1 : Modified (expected output: Modified)

After function
        myvar = 2 (expected value: 1)                <<--- Again, clobbered...
      myfunc1 : Original (expected output: Original)

Before namespace y
      thisvar = 1
      myfunc2 : Original (expected output: Original)

In namesapce y
      thisvar = 1 (expected value: 1)
      myfunc2 : Original (expected output: Original)

      thisvar = 2 (expected value: 2)
      myfunc2 : Modified (expected output: Modified)

Outside namespace y
      thisvar = 1 (expected value: 1)
      myfunc2 : Original (expected output: Original)
   .y.thisvar = 2 (expected value: 2)
   .y.myfunc2 : Modified (expected output: Modified)

#

ご覧のとおり、namespace xafterとafter(それぞれグローバルに定義され、関数内で定義されています)の値はすべて、名前空間内に割り当てられた値でオーバーライドされていますが、オーバーライドされません。myvarthisvarmyfunc1

これが予想される動作ですか?

ノート私はサブシェルについて知っています。しかし、サブシェルにメモリリークがあるため、名前空間を使ってみました。私が使用するコード:

  • さまざまな変数と関数を定義します。
  • 周期を入力し、
    • 何かをしなさい
    • 関数を呼び出す
      • サブシェルから:
        • 特定の変数と関数定義のポイント(すでに定義されているか定義されていない可能性があります)その他の値既存の変数と関数)
        • 次の変数と関数を使用してください
  • 必要なことをもっとやるオリジナル変数と関数の定義

サブシェル方法の問題は、シャットダウン時にリークされるメモリ量が二次的に増加するように見えることです(たとえば、ループを約1000回繰り返すと、4 GBに近いリークが発生します...)。

名前空間アプローチがリークを処理することを確認しました。問題は、更新された変数定義が既存の変数定義を破損して後で問題を引き起こす可能性があることです。

どんな提案がありますか? !

ベストアンサー1

おすすめ記事