函数内部定义的 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)

#

如您所见, after和namespace x的值(分别在全局和函数内定义)都已被命名空间内分配的值覆盖,但并未被覆盖。myvarthisvarmyfunc1

这是预期的行为吗?

笔记我知道子 shell。但是,由于子 shell 存在内存泄漏,我尝试使用命名空间。我正在使用的代码:

  • 定义了一堆变量和函数
  • 进入一个循环,
    • 做一些事情
    • 调用一个函数
      • 在子外壳中:
        • 某些变量和函数定义中的点(可能已经定义,也可能已经定义)不同的价值观现有的变量和函数)
        • 使用这些变量和函数
  • 做更多可能需要的事情原来的变量和函数定义

subshel​​l 方法的问题在于,当它退出时,我们泄漏的内存量似乎呈二次方增加(例如,在循环迭代约 1000 次之后,我们泄漏了接近 4GB...)

我已经验证命名空间方法可以处理泄漏;问题在于更新的变量定义正在破坏现有的变量定义,这会导致以后出现问题。

有什么建议么?!

相关内容