循环遍历数组,防止通配符扩展(*)

6

我正在尝试解决BASH中看起来微不足道的问题,但我很难找到正确的语法。我想要循环遍历一个值数组,其中之一是星号(*),在此过程中我不希望发生任何通配符扩展。

 WHITELIST_DOMAINS="* *.foo.com *.bar.com"
 for domain in $WHITELIST_DOMAINS
 do
    echo "$domain"
 done

我有以上内容,现在想输出以下结果:
 *
 *.foo.com
 *.bar.com

与上面不同的是,我在当前目录下得到一个目录列表,然后是*.foo.com和*.bar.com

我知道我需要在某个地方进行转义或引用...我的大脑仍然被清晨的薄雾笼罩着。

我已经查阅了这些问题:

如何在bash中对变量中的通配符扩展进行转义?

停止shell通配符字符扩展?

2个回答

7
你的问题在于你想要一个数组,但是你写了一个包含元素并以空格分隔的单个字符串。应该使用一个数组来解决这个问题。
WHITELIST_DOMAINS=('*' '*.foo.com' '*.bar.com')

在变量替换时,始终使用双引号(即"$foo"),否则shell将把变量的值分成单独的单词,并将每个单词视为文件名通配符模式。对于命令替换也是如此:"$(somecommand)"。对于数组变量,请使用"${array[@]}"来扩展为数组元素的列表。

for domain in "${WHITELIST_DOMAINS[@]}"
 do
    echo "$domain"
 done

更多信息请参阅有关数组的bash常见问题解答


手掌紧紧地贴在脸上——我应该知道我没有使用数组,谢谢你这么清楚而迅速地指出来。 - Tal
否则,shell会将变量的值拆分为单独的单词,并将每个单词视为文件名通配符模式。当在多种语言之间移动时,这方面的shell脚本可能是最难记住的。感谢您刷新我的记忆。 - Tal

2
您可以使用数组来存储它们:
array=('*' '*.foo.com' '*.bar.com')

for i in "${array[@]}"
do
    echo "$i"
done

这个解决方案与被接受的答案相同,只是@Giles在未来通过Google漫步的用户提供了更多有用的解释。我选择接受他的评论而不是你的,以便完整和永久保存。 - Tal

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