将数组存储为非交互式 shell 的环境变量

将数组存储为非交互式 shell 的环境变量

有几个问题可以解决问题,但我想尝试以下方法:

在这个问题中,我基本上将数组作为环境变量,然后尝试将字符串存储到单独的数组元素中。

a=('Apple Tomato' 'Banana Carrot') bash -c \
'b=($(echo "${a}")); echo -e "${b[0]}\n"; echo "${b[1]}";'

输出

(Apple

Tomato

期望的输出:

苹果番茄

香蕉胡萝卜

观察:

另外,如果原始数组在单引号数组元素内有双引号,引号是否会被保留。例如:a=('Apple "Tomato"' 'Banana "Carrot"')

答案1

环境变量是简单的字符串键值对。数组不能是环境变量。

但是,您可以将数组的值传递abash -c脚本:

bash -c 'printf "%s\n" "$@"' bash "${a[@]}"

b或者,如果您想在脚本中调用数组:

bash -c 'b=( "$@" ); printf "%s\n" "${b[@]}"' bash "${a[@]}"

在这两种情况下,数组的元素a都在脚本的命令行上传递。这意味着它们将出现在脚本中的"$@"(in "$1""$2"等) 中bash -c

你的问题中发生的情况是命令

a=('Apple Tomato' 'Banana Carrot') bash -c '...'

将变量设置a为字符串(Apple Tomato Banana Carrot)。这是脚本a中环境变量的值bash -c

$ a=('Apple Tomato' 'Banana Carrot') bash -c 'printf "%s\n" "$a"'
(Apple Tomato Banana Carrot)

如果你真的如果需要将数据作为环境变量传递,您可以通过决定分隔符然后将数组展平为单个字符串来实现。

例如,使用:

IFS=:
b="${a[*]}" bash -c 'set -f; IFS=:; a=( $b ); printf "%s\n" "${a[@]}"'

这将构造字符串Apple Tomato:Banana Carrot并使用该字符串创建环境变量b作为脚本的值bash -c

然后该脚本再次分裂b:并将分裂的单词分配给它自己的a数组。

我需要set -f在脚本中使用,以避免在使用不带引号的情况下对分割单词调用文件名通配符$b

然后,您还希望恢复和父 shellIFS中的原始值bash -c(您可能希望将旧值存储在变量中以使其更容易)。您可能还想在bash -c脚本中再次启用文件名通配,使用set +f.

ifs=$IFS; IFS=:
b="${a[*]}" bash -c 'set -f; ifs=$IFS; IFS=:; a=( $b ); IFS=$ifs; unset ifs; set +f; printf "%s\n" "${a[@]}"'
IFS=$ifs; unset ifs

相关内容