Bash 中可能存在错误?: foo() { echo "${var[0]}"; }; var=(bar baz) foo

Bash 中可能存在错误?: foo() { echo "${var[0]}"; }; var=(bar baz) foo

操作系统:Ubuntu 16.04.3

:重击 4.3.48


我知道可以暂时更改变量的内容,如 中所示var=value command,这可能是IFS= read -r var最值得注意的情况。

和,感谢格雷格的维基,我也明白:

# Why this
foo() { echo "$var"; }
var=value foo

# And this does work
var=value; echo "$var"

# But this doesn't
var=value echo "$var"

我无法理解的是:

$ foo() { echo "${var[0]}"; }
$ var=(bar baz) foo
(bar baz)

据我所知(并遵循前面示例的逻辑),它应该打印bar,而不是(bar baz)

这种情况只发生在我身上吗?这是预期的行为吗?我错过了什么?或者这是一个错误?

答案1

一般调用:

var=value cmd

其中cmd是一个不可移植的函数。

对于bash,这只适用于标量变量(并且x=(...)解析为数组但分配为标量),如果这样做,则范围界定会存在许多问题,对于ksh93yash,它可以工作,但变量定义仍然存在。使用 时mksh,您会收到语法错误。在 Bourne shell 中,它根本不起作用,即使对于标量变量也是如此。

另请注意,即使使用标量变量,该变量最终是否会被出口函数内(即传递给正在执行的命令)因 shell 而异(在 bash、yash、mksh、zsh 中,但在 ksh、ash 中则不然)。

它只能按照您期望的方式工作zsh。请注意,zsh数组索引从 1 开始。

bash-4.4$ zsh
$ a=(before value)
$ f() echo $a[1]
$ a=(temp value) f
temp
$ echo $a[1]
before

答案2

这不仅仅是一个错误,它似乎是一个未实现的功能,并且没有计划这样做。这邮件列表帖子从 2014 年起,创作者就给出了这样的信息:

幸运的是,在 bash 4.3(补丁级别 25)中,您不能仅使用 -DARRAY_EXPORT 并获取数组变量导入/导出。该代码无法编译,如果您修复它,它就不会链接,如果您修复它,那么您最终会遇到以下问题。

仅仅为了这个就需要经历很多麻烦。我没有任何启用数组导出的计划。

从 Bash 的最新 git 存储库中提取内容如下variables.c

  #  if ARRAY_EXPORT
        /* Array variables may not yet be exported. */

表明那里的一切都不完整。

答案3

来自man bash的BUGS部分(版本是bash4.3):

错误

   Array variables may not (yet) be exported.

下一个代码演示了,仅当函数运行时,环境中才存在临时变量。当函数完成后,临时变量就消失了。

### defining the "bar" function
### it pass all environment variables to the "grep" command
### and the "grep" prints the only "my_var" variable from it
bar() { env | grep my_var=; }

### calls the "bar" function with the temporary 
### variable "my_var" created and assigned.
my_var=one bar

my_var=one         ### The output. The environment contains the "my_var" variable

### checks, does the environment still have the "my_var" variable
### (It doesn't have.)
env | grep my_var=
                   ### The output is empty,
                   ### the environment doesn't contain the "my_var" variable

相关信息:

相关内容