bash 循环中的 @ 和 *

bash 循环中的 @ 和 *

我发现以下两个循环产生相同的输出。您能帮我理解在这种特殊情况下@和之间有什么区别吗?*

#!/bin/bash

ips=(8.8.8.8 8.8.4.4)

for ip in ${ips[@]}; do
    echo $ip
done

for ip in ${ips[*]}; do
    echo $ip
done

它们都产生相同的结果:

8.8.8.8
8.8.4.4

答案1

Bash 手册页引用

数组的任何元素都可以使用 ${name[subscript]} 引用。需要使用大括号以避免与路径名扩展发生冲突。如果下标是 @ 或 * ,则该单词将扩展到 name 的所有成员。仅当单词出现在双引号内时,这些下标才会不同

如果单词用双引号引起来,则 ${name[*]} 扩展为单个单词,每个数组成员的值由 IFS 特殊变量的第一个字符分隔,而 ${name[@]} 扩展每个数组元素名称为一个单独的单词。

当没有数组成员时,${name[@]} 扩展为空。如果双引号扩展发生在单词内,则第一个参数的扩展与原始单词的开头部分连接,最后一个参数的扩展与原始单词的最后部分连接。

意思是:

munai@munai-devops:~$ declare -a array
munai@munai-devops:~$ array=(1 2 3)
munai@munai-devops:~$ bakIFS=$IFS
munai@munai-devops:~$ IFS=","
munai@munai-devops:~$ echo "${array[*]}"
1,2,3
munai@munai-devops:~$ echo "${array[@]}"
1 2 3

答案2

正如您所注意到的,两者之间没有区别 - 即当数组没有被引用时。

"${arr[*]}"将数组扩展为一个元素,而 "${arr[@]}"扩展每个元素但保留空格 (IFS)。

第一个数组不会改变,但第二个数组将具有以下输出:

8.8.8.8 8.8.4.4

相关内容