是否有一种不太复杂的方法可以在函数内本地设置 $path 数组?

是否有一种不太复杂的方法可以在函数内本地设置 $path 数组?

有没有$path比以下代码片段中显示的更省力的方法来设置数组的本地版本?

foo () {
    local holdpath
    holdpath=($path)
    local path
    path=($holdpath)
    if ( some_condition ) path=( $PREFIX $path )

    # do stuff
}

我特指的是歌舞表演holdpath……

如果我定义

foo () {
    local path=($path)
    if ( some_condition ) path=( $PREFIX $path )

    # do stuff
}

...第一个赋值会path触发bad pattern错误。当然,如果我定义

foo () {
    local path
    path=($path)
    if ( some_condition ) path=( $PREFIX $path )

    # do stuff
}

...第一个赋值path没有什么区别(即可以省略而不改变结果);有或没有它,$path都将是空的。

编辑:

以下脚本测试了我迄今为止收到的各种建议:

foo_0 () {
  echo ${#path}
  local PATH=$PATH
  echo ${#path}
}

foo_1 () {
  echo ${#path}
  eval "local path; path=(${(q)path})"
  echo ${#path}
}

foo_2 () {
  echo ${#path}
  eval "$(local -p path)"
  echo ${#path}
}

for i ( 0 1 2 ) {
  fn=foo_$i
  echo "# $fn"
  $fn
  echo
}

输出是:

# foo_0
22
22

# foo_1
22
1

# foo_2
22
22

foo_0因此和的输出foo_2至少与我想要实现的目标一致。正如上面给出的那样,有些东西不起作用,但我在分配给 时foo_1去掉了,即(q)path

foo_1 () {
  echo ${#path}
  eval "local path; path=($path)"
  echo ${#path}
}

foo_0...那么输出与和 的输出一致foo_2。不幸的是,即使阅读了q几次限定符的文档,我也不太明白它在原始配方中应该做什么。

另外,我无法理解为什么以下命令行变体foo_0与上面的不同:

% (foo_0a () { echo ${#path}; local PATH=$PATH; echo ${#path} }; foo_0a)
22
1

FWIW,相应的命令行变体foo_1foo_2产生与脚本中原始结果相同的结果:

% (foo_1a () { echo ${#path}; eval "local path; path=(${(q)path})"; echo ${#path} }; foo_1a)
22
1
% (foo_2a () { echo ${#path}; eval "$(local -p path)"; echo ${#path}; }; foo_2a)
22
22

此外,在上述所有情况下,echo ${#path}产生1而不是22原因是局部$path变量包含单个字符串中的所有单独路径,并用空格分隔。

答案1

使用标量PATH形式而不是数组path。使其中任何一个有效地本地化都使它们都本地化,因此:

foo() {
  local PATH=$PATH
  if ( some_condition ) path=( $PREFIX $path )

  # do stuff
}

(请注意,如果某些路径组件嵌入了 ,则这将不起作用:。)

遗憾的是,无法在一条语句中初始化局部数组参数,因此无法使用其原始值来初始化局部数组参数。

答案2

而对于捆绑数组,你可以使用里奇的回答,一般情况下,你可以这样做:

foo() {
  eval "local array; array=(${(q)array[@]})"
  ...
}

(q)是引用数组的元素。例如,对于$PATHlike的值/foo bar:/x$y"${(q)path[@]}"将扩展为/foo\ bar /x\$y。我们需要转义这些空格和美元字符,因为该字符串被传递给eval.

你还可以这样做:

foo() {
  eval "$(local -p array)"
  ...
}

它适用于任何类型的变量,但这会产生一个额外的过程。

相关内容