将函数移至新脚本

将函数移至新脚本

有没有办法既可以$val进入a ()但又不被看到b ()

set -u -e -o pipefail


a () {
  local +x val="myval"
  echo "in a: VAL= $val"
  b
}

b () {
  echo "in b: VAL= $val"
}

a

生产:

in a: VAL= myval
in b: VAL= myval  # This should not happen.

我希望使用local/ typesetoptions 而不是使用子 shell 来保护变量不被其他函数看到。

我已经检查过手动的(函数部分,排版部分)似乎没有办法。然而,我可能很容易错过一些东西。

答案1

b您可以作为新进程运行,而不是使用子 shell 限制变量。然后,除了您选择导出的变量之外,它将无法访问调用者的任何变量。

将函数移至新脚本

如果您只需要单个函数,请将整个函数移至单独的脚本中。

b:

#!/usr/bin/env mksh
set -u -e -o pipefail

echo "in b: VAL= $val"

输出:

in a: VAL= myval
./b[4]: val: parameter not set

使用包装函数

如果您有很多需要此功能的函数,那么您可以将它们全部移动到一个文件中,并包含一个包装函数以进行源代码和执行。

funcs:

#long options not passed on by -$-
set -o pipefail

#execute function without inheriting environment variables
function ni () {
  WHERE="${_%/*}"
  mksh -$- -c "source $WHERE/funcs ; $*"
}

function a () {
  local +x val="myval"
  echo "in a: VAL= $val"
  ni b
}

function b () {
  echo "in b: VAL= $val"
}

这个“库”需要source从主脚本中获取:

#!/usr/bin/env mksh

set -e -u -o pipefail

WHERE="${_%/*}"
source $WHERE/funcs

a

这样做的缺点是您会丢失错误的位置(脚本和行号):

in a: VAL= myval
mksh: val: parameter not set

答案2

不。

然而,如果您的调用b是尾部调用并且您“仅”需要构造其参数,则有一种方法可以做到这一点,我在“找出类路径然后运行 ​​JAR”脚本中使用了该方法。

function a {
    local val …

    # do something with local variables

    # construct arguments by setting the global variable _ to it
    set -A _ -- b arg1…
    # could even unset -f a here
}
a
"${_[@]}"

我的剧本我在调用外部命令时使用exec "${_[@]}"最后一行,我使用局部变量技术来避免意外污染任何导出的环境变量。

也许这有帮助?

完全披露:我是mksh开发人员。

相关内容