据我所知,有两种方法可以在bash函数中创建局部变量:创建子壳或将每个变量声明为局部。

例如:

# using local
function foo
{
  local count
  for count in $(seq 10)
  do
    echo $count
  done
}

或者

# using subshell
function foo
{
  (
    for count in $(seq 10)
    do
      echo $count
    done
  )
}

偏见使用子壳的版本更简单地编写,因为您不必关心声明本地所有变量(更不用说(环境)变量,由诸如工具创建/导出。 getopts)。但是我可以想象,创建一个子壳具有开销。

那么更好的方法是什么?什么是利弊?

有帮助吗?

解决方案

创建子壳涉及 fork(), ,因此与本地变量相比,它绝对具有开销。虽然子壳价格便宜 - 您不必担心他们在需要时的费用 - 它们不是免费的。

如果您的脚本将被大量使用,并且性能确实很重要(因此,您将有数百个用户同时运行它,每天很多次),那么您可能会担心子壳的性能成本。 OTOH,如果您每月运行一次,并且整个脚本的运行持续不到10秒,那么您可能不会。

但是,就清晰度而言,要明确并声明变量要好得多 - 它降低了脚本破裂的风险,因为有人出现并说“显然不需要这个子壳”(这确实是不需要的” t;我想从您的功能中删除子壳)。

查看Perl脚本的演变。他们最初是自由的,随时可以使用变量。它们逐渐变得更加严格,正常样式现在是所有变量的前列。在某种程度上,贝壳已经遵循了类似的路径 - 但不像perl那样严格。尴尬也是一个有趣的案例研究。除非它们是对函数的参数,否则其函数使用全局变量,这会导致用3个主动参数(SAS)和5个有效定义局部变量的不活动参数编写函数。尽管“起作用”,但它有点古怪。

其他提示

现在,确保所有函数始终将所有变量声明为本地,都非常困难。

我认为这非常容易出错,并且更喜欢始终使用子壳功能:

f() (
 echo "we are a subshell"
)

无需声明本地变量 - 但也没有办法更改全局变量。我认为这很好!

另一个结果是,您始终需要检查此类功能的返回 /退出代码并采取相应的行动!这是因为您无法从子壳功能中退出脚本!

f() (
   echo "Trying to exit"
   exit 1
)

f
echo "Did not exit"

这不会退出您的脚本。您需要这样做:

f() (
   echo "Trying to exit"
   exit 1
)

f || exit $?
echo "Did not exit"

这将退出

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top