我不知道为什么我不能在脚本中使用 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[*]}
元素,此处设置为。请注意,如果这样做,字符串的元素将是arr
IFS
:
分开(不是分隔的) 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
最好的祝愿