Possible bug in Bash?: foo() { echo "${var[0]}"; }; var=(bar baz) foo

Generally calling:

var=value cmd

where cmd is a function is not portable.

With bash, that only works for scalar variables (and with x=(...) parsed as an array but assigned as a scalar) and there are a number of issues with scoping if you do that, with ksh93 and yash, it works but the variable definition remains afterwards. With mksh, you get a syntax error. In the Bourne shell, it didn't work at all, even for scalar variables.

Also note that even with scalar variables, whether the variable ends up being exported within the function (that is, passed to commands being executed) varies from shell to shell (it is in bash, yash, mksh, zsh, but not in ksh, ash).

It only works the way you'd expect with zsh. Note that zsh array indices start at 1.

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

It's not just a bug, it seems to be an unimplemented feature with no plans of ever being so. This mailing list post from 2014 has this from the creator:

Fortunately, in bash 4.3 (patchlevel 25), you cannot just -DARRAY_EXPORT and get array variable import/export. The code doesn't compile, and if you fix that, it does not link, and if you fix that, well, you end up with the following issue.

That's a ton of trouble to go through just for this. I don't have any plans to enable array export.

Pulling from the latest git repo for Bash has this in variables.c:

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

Suggesting that whatever is there isn't complete.


From the man bash's BUGS section (the version of the bash is 4.3):

BUGS

   Array variables may not (yet) be exported.

The next code demonstrates, that a temporary variable exists in the environment, only while the function is running. When the function is completed, the temporary variable disappears.

### 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

Related information:

  • Answer about the VAR=VALUE some-command construction.
  • Exporting an array in bash script
  • bash: set array env variable and de-referencing it from any shell script fails

Tags:

Bash

Array