之前从网上找了很多关于 IFS 的二手资料,每次用每次都得再看一遍,理解还是不够透彻。最近对照着 man bash
,终于把这个 IFS 搞清楚了。
IFS 其实只在 3 个地方发挥作用:
"$*"
可以看到,其实只有 bash 本身和 read 命令会用到 IFS 这个环境变量。所以,除了
IFS=xxx bash -c "xxx"
和
IFS=xxx read a b c
之外,任何的 IFS=xxx
临时环境变量都是不会起到任何作用的。
先写一个小的辅助程序,名为 argsecho,用于直观展示所有参数列表。
import sys
for ind, arg in enumerate(sys.argv[1:], 1):
print("${}: {}".format(ind, arg), flush=True)
$*
对于一个数组
arr=(1 2 3 4 5)
"${arr[@]}"
会展开为 "1" "2" "3" "4" "5"
,是最忠实于原数组的展开方式。通常用于将参数列表原封不动传递给子命令。展开的过程中不涉及 IFS。
$ argsecho "${arr[@]}"
$1: 1
$2: 2
$3: 3
$4: 4
$5: 5
${arr[*]}
则会读取 IFS 的第一个字符,作为分隔符。设为 c,则会展开为 "1c2c3c4c5"
。如果 IFS 为空,则直接拼接,不插入分隔符,直接展开为"12345"
。