如何在bash中导出关联数组(散列)?
相关,但不是以下文件的副本: 我可以定义和使用bash散列,但即使使用-x标志,也无法导出它。例如,以下用于导出(和测试导出)普通字符串变量:如何在bash中导出关联数组(散列)?,bash,hash,export,Bash,Hash,Export,相关,但不是以下文件的副本: 我可以定义和使用bash散列,但即使使用-x标志,也无法导出它。例如,以下用于导出(和测试导出)普通字符串变量: aschirma@graphics9-lnx:/$ export animal_cow="moo" aschirma@graphics9-lnx:/$ bash -c "echo \$animal_cow" moo aschirma@graphics9-lnx:/$ 但是,如果我尝试导出散列: aschirma@graphics9-lnx:/$ de
aschirma@graphics9-lnx:/$ export animal_cow="moo"
aschirma@graphics9-lnx:/$ bash -c "echo \$animal_cow"
moo
aschirma@graphics9-lnx:/$
但是,如果我尝试导出散列:
aschirma@graphics9-lnx:/$ declare -A -x animals
aschirma@graphics9-lnx:/$ animals[duck]="quack"
aschirma@graphics9-lnx:/$ echo ${animals[duck]}
quack
aschirma@graphics9-lnx:/$ bash -c "echo \${animals[duck]}"
aschirma@graphics9-lnx:/$
嵌套的bash shell似乎在其作用域中没有散列。我也通过手动输入嵌套的bash shell并尝试以交互方式使用散列来验证这一点。将数组变量编码到环境中并不是一个好方法。看见
(Chet Ramey是bash的维护者)这有点老了,但我回答说,无论如何,你可以使用临时文件。如果你做得对,你可以把它包装起来,像数组一样使用它们。例如,使用此功能:
var() { # set var or add comtent
case $1 in
*=|*=*)
local __var_part1=$( echo "$1" | sed -e 's/=.*//' -e 's/[+,-]//' ) # cut +=/=
local __var_part2=$( echo "$1" | sed -e 's/.*.=//' )
local __var12=$tmp_dir/$__var_part1
mkdir -p ${__var12%/*} #create all subdirs if its an array
case $1 in
*+=*)
# if its an array try to add new item
if [ -d $tmp_dir/$__var_part1 ] ; then
printf -- $__var_part2 > $tmp_dir/$__var_part1/\ $((
$( echo $tmp_dir/$__var_part2/* \
| tail | basename )\ + 1 ))
else
printf -- "$__var_part2" >> $tmp_dir/$__var_part1
fi
;;
*-=*) false ;;
# else just add content
*) printf -- "$__var_part2" > $tmp_dir/$__var_part1 ;;
esac
;;
*) # just print var
if [ -d $tmp_dir/$1 ] ; then
ls $tmp_dir/$1
elif [ -e $tmp_dir/$1 ] ; then
cat $tmp_dir/$1
else
return 1
fi
;;
esac
}
# you can use mostly like you set vars in bash/shell
var test='Hello Welt!'
# if you need arrays set it like this:
var fruits/0='Apple'
var fruits/1='Banana'
# or if you need a dict:
var contacts/1/name="Max"
var contacts/1/surname="Musterman"
这不是最快的方法,但它非常灵活、简单,几乎可以在所有shell中使用。为了解决这个苛刻的Bash限制,我使用了“序列化到临时文件”方法。您可以导出普通变量,以便通过filepath传递数组(关联)。当然,这也有局限性,但有时是有效的,而且已经足够好了
declare -A MAP # export associative array
MAP[bar]="baz"
declare -x serialized_array=$(mktemp) # create temporary variable
# declare -p can be used to dump the definition
# of a variable as shell code ready to be interpreted
declare -p MAP > "${serialized_array}" # serialize an array in temporary file
# perform cleanup after finishing script
cleanup() {
rm "${serialized_array}"
}
trap cleanup EXIT
# ... in place where you need this variable ...
source "${serialized_array}" # deserialize an array
echo "map: ${MAP[@]}"
再深入一点,环境是由操作系统定义的;shell只是提供了一种填充环境的方法。POSIX(用作示例)没有为其环境变量的结构化数据提供定义;每个值都只是一个字符串。
bash
将数组(常规或关联)转换为单个字符串的任何尝试都将特定于bash
。这造成了一场可移植性噩梦,因为环境不再仅仅由操作系统定义,而是由任何用户决定使用的任何方法来启动程序。如果您的用户可以接受以GNU并行方式包装它,您可以使用env_parallel
:您可以使用进程替换来代替手动创建和删除文件:DEF_MAP=