带/不带空格的引号之间的Bash差异



我试图检查数组是否包含值,我发现检查Bash数组是否包含值

它不适合我,这是因为我决定删除引号周围的空格,像这样:

words=(aa bb cc)
[[ " ${words[@]} " =~ " a " ]] && echo "YES" || echo "NO"; # This is the real answer, and it works
------
[[ "${words[@]}" =~ "a" ]] && echo "YES" || echo "NO"; # This does not work. Why???
  1. 用空格包围它们和不用空格包围它们有什么区别?

为了我的好奇心。在我提到的上一个问题中,一些答案/评论如下:

${array[*]}和其他${array[@]}

  1. 他们是否都"iterate"以同样的方式通过循环吗?

[[ string =~ regex ]]检查regex是否匹配string的子字符串。操作符for entry in "${words[@]}"那样遍历数组条目。它甚至不能处理数组。

[[ " ${words[@]} " =~ " a " ]]只是一个hack用于查找数组元素。数组被转换成一个字符串,其中所有数组项都被空格包围。然后,使用字符串搜索来搜索元素。只有在数组项本身不包含空格的情况下,才能可靠地工作。

关于${array[*]}${array[@]}的区别,请参阅bash的手册:

如果单词是双引号,${name[*]}展开成一个单词每个数组成员的值由IFS变量的第一个字符分隔[默认=空格]${name[@]}扩展每个元素将名称转换为单独的单词.

所以在这种情况下,*将是写[[ " ${words[*]} " =~ " a " ]]的逻辑方式,因为它相当于[[ " aa bb cc " =~ " a " ]]
@在这里也起作用有点奇怪,因为[[ " aa" "bb" "cc " =~ " a " ]]给出了语法错误。Bash容忍[[中的@被误用可能是一个未记录的"特性"。与[[中禁用的分词功能相关。对于基本的POSIX测试命令[,*@之间的差异与预期的一样,这意味着a=("x" "=" "y"); [ "${a[@]}" ]失败,因为x != y。