在bash中是否可以使用$array=()?

10

首先,这是我在本论坛的第一个问题,如果格式混乱请原谅。其次,我没有编写太多的bash脚本,并且我编写的脚本之间的时间相当长。

话虽如此,这是我的问题。

在Bash中是否可以做到像这样清除数组 $array 的内容:
$array=()

基本上这就是我想要做的事情。我有一个变量,其中包含数组变量名称:

array1=()  
array2=()  
arrayList="array1 array2"  


# In a function far far away
for array in $arrayList
do  
    eval arr=("\"\${$array[@]\"")  

    for index in ${!arr[@]}
    do
        echo "${arr[$index]}"
    done
    # Here is the big "?", I like to clear the array that $array refers to.
    $array=()  
done
我的数组包含了包含空格的字符串,因此我使用eval语句。不确定是否需要它,但至少它是有效的。脚本基本上按照我想要的方式运行,但我需要清除$arrayList中的数组,并且我不想在某个地方硬编码它,即使那样也很容易。

请参考http://mywiki.wooledge.org/BashFAQ/048,关于使用eval的问题--简而言之,这并不是一个建议性的做法。 - Charles Duffy
谢谢提供链接!我看到eval不是推荐的方法,因为你可以注入一些不好的东西,甚至在不小心执行时自己做一些愚蠢的事情。虽然这个脚本只会被我自己使用,但我会考虑换另一个解决方案。 - Qben
也许你真正想要的是关联数组。它们在bash 4中可用。 - Dunes
@Dunes 嗯,你可能是对的。刚刚在查看查尔斯·达菲在下面回答中提供的BashFAQ#6链接时读到了一些关于它们的内容。谢谢。 - Qben
3个回答

12

最简单的方法可能就是将它们设置为未定义状态(unset)。在大多数情况下,未定义的变量和空数组的行为几乎相同,因此 unset $array 应该能够正常工作。


你的意思是说这么简单吗? :) 我原本以为它只会取消 $array 变量,而 $array1 和 $array2 仍然存在。但在测试了你的建议后,看起来很有前途。非常感谢! - Qben
1
@Qben unset array 将取消数组变量本身;unset $array 的作用如广告所述。 - Charles Duffy
@Qben:当您间接地执行unset操作时,我建议将变量用引号括起来: unset "$array" - Dennis Williamson
1
使用unset将导致您丢失变量的任何属性。例如,我有一个本地变量,我取消设置它,现在它不再是本地的并且破坏了一切。尽管这让我很痛苦,但eval "$1=()"是我唯一有效的方法 :-\ - Andy

1

你永远不能这样做:$foo=bar,因为这不是在bash中进行间接赋值的方式。不幸的是,尽管在ksh93中有能力进行间接数组分配,但在bash中它并没有被正式记录为可用特性。

引用BashFAQ #6(如果您想了解更多关于使用间接变量的信息,请全文阅读):

We are not aware of any trick that can duplicate that functionality in POSIX or Bourne shells (short of using eval, which is extremely difficult to do securely). Bash can almost do it -- some indirect array tricks work, and others do not, and we do not know whether the syntax involved will remain stable in future releases. So, consider this a use at your own risk hack.

# Bash -- trick #1.  Seems to work in bash 2 and up.
realarray=(...) ref=realarray; index=2
tmp="$ref[$index]"
echo "${!tmp}"            # gives array element [2]

# Bash -- trick #2.  Seems to work in bash 3 and up.
# Does NOT work in bash 2.05b.
tmp="$ref[@]"
printf "<%s> " "${!tmp}"; echo    # Iterate whole array.

然而,清除操作更简单,因为unset $array将会很好地工作。


我认为他不想解除引用,他只是想清空数组。 - c00kiemon5ter
@c00kiemon5ter 当然可以,但仅回答如何清空数组将使某些人在尝试做其他事情时感到困惑。我已经添加了一个直接的答案,但认为回答更大的问题“我应该怎么做而不是$array=...”也有价值。 - Charles Duffy
间接赋值可以这样实现:declare $foo=bar - Dennis Williamson
@DennisWilliamson ...或者使用printf -v "$foo" '%s' bar,或者使用链接FAQ中提供的任何其他机制。对于非数组变量来说并不难 -- "你永远不能做$foo=bar" 只是表示 $ 在左侧的赋值即使对于非数组也是无效的,并不意味着没有可行的语法存在。 - Charles Duffy

-1
array=()

它清空了数组。我想这就是你想要的。


不,不是这样的,你没有抓住重点。问题是关于间接寻址的。 - Adrian Frühwirth

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接