无法使用数组作为环境变量

无法使用数组作为环境变量

我不知道为什么我不能在脚本中使用 env 数组变量?
在我~/.bashrc~/.profile

export HELLO="ee"
export HELLOO=(aaa bbbb ccc)

在外壳中:

> echo $HELLO
ee
> echo $HELLOO
aaa
> echo ${HELLOO[@]}
aaa bbbb ccc

在脚本中:

#!/usr/bin/env bash
echo $HELLO
echo $HELLOO
echo ${HELLOO[@]}
---
# Return 
ee

为什么 ?

答案1

数组bash不能是环境变量,因为环境变量只能是键值字符串对。

您可以像 shell 对其$PATH变量所做的那样操作,该变量本质上是一个路径数组;将数组转换为字符串,并用数组值中不存在的某些特定字符分隔:

$ arr=( aa bb cc "some string" )
$ arr=$( printf '%s:' "${arr[@]}" )
$ printf '%s\n' "$arr"
aa:bb:cc:some string:

或者更整洁,

arr=( aa bb cc "some string" )
arr=$( IFS=:; printf '%s' "${arr[*]}" )
export arr

的扩展将是由 的第一个字符分隔的数组${arr[*]}元素,此处设置为。请注意,如果这样做,字符串的元素将是arrIFS:分开(不是分隔的) by :,这意味着您将无法区分末尾的空元素(如果有的话)。


使用环境变量将值传递给脚本的另一种方法是(显然?)使用命令行参数:

arr=( aa bb cc )

./some_script "${arr[@]}"

然后,脚本将使用位置参数$1、等,或使用以下命令一一访问传递的参数:$2$3$@

printf 'First I got "%s"\n' "$1"
printf 'Then  I got "%s"\n' "$2"
printf 'Lastly there was "%s"\n' "$3"

for opt in "$@"; do
    printf 'I have "%s"\n' "$opt"
done

答案2

数组是 bash 特定的。环境变量是名称-值对。

阅读环境变量规范,其中部分内容是:

环境变量的值是一串字符。对于 C 语言程序,当进程开始时,应提供称为环境的字符串数组。该数组由外部变量指向环境,定义为:

extern char **environ;

这些字符串的形式为名称=值;名字不得包含字符“=”。

答案3

当前阵列出口情况 10/2021

数组导出尚未完全实现。您可以使用命令克隆源代码git clone https://git.savannah.gnu.org/git/bash.git ~/bash-src。查看 bash 源~/bash-src/config-top.h代码中的注释行 154:

/* Define to 1 if you want to be able to export indexed arrays to processes
   using the foo=([0]=one [1]=two) and so on */
/* #define ARRAY_EXPORT 1 */

此外,第 429 行的代码部分~/bash-src/variables.c表示

#if defined (ARRAY_VARS)
#  if ARRAY_EXPORT
      /* Array variables may not yet be exported. */
      if (*string == '(' && string[1] == '[' && string[strlen (string) - 1] == ')')
    {
      string_length = 1;
      temp_string = extract_array_assignment_list (string, &string_length);
      temp_var = assign_array_from_string (name, temp_string, 0);
      FREE (temp_string);
      VSETATTR (temp_var, (att_exported | att_imported));
      array_needs_making = 1;
    }
      else
#  endif /* ARRAY_EXPORT */
#endif

所以基本上这个问题还需要做更多的工作。

解决方法

同时您可以导出BASH_ENV可以指向环境脚本的变量。我将其放入/etc/bash.environment并在那里声明系统范围的数组。您~/.bashrc可以包含类似的内容export BASH_ENV="~/.bash.environment",现在当前用户执行的每个 bash 进程都将获取此文件。

正如@他们在下面提到的,~/.bashrc需要相应的配置才能在交互式和非交互式 shell 上生效:

[ -r "~/.bash.environment" ] \
&& source "~/.bash.environment" \
&& export BASH_ENV="~/.bash.environment"

最后是你的环境:

# ~/.bash.environment
export HELLO="ee"
export HELLOO=(aaa bbbb ccc)

非持久性解决方法

快速而肮脏地传递数组的非持久解决方案可能如下所示,将进程替换创建的命名管道分配<()BASH_ENV环境变量:

BASH_ENV=<(declare -p HELLO HELLOO) your_script.sh

最好的祝愿

相关内容