每当我阅读 IFS 时,它总是在上下文中read
(或者至少我如此理解)。
IFS 是否用于除read
shell 内置之外的任何其他用途?
POSIX shell 手册对字段拆分有以下说明:
在参数扩展(Parameter Expansion)、命令替换(Command Substitution)和算术扩展(Arithmetic Expansion)之后,shell会扫描没有发生在双引号中的扩展和替换的结果进行字段拆分,可以导致多个字段。
shell 将 IFS 的每个字符作为一个分隔符,并使用分隔符作为字段终止符,将参数扩展、命令替换和算术扩展的结果拆分为字段。
如果IFS的值是一个
<space>
,<tab>
和<newline>
,或者如果它是未设置的任何序列<space>
,<tab>
或<newline>
在开始时或输入的结束字符应当被忽略和输入内的那些任何字符序列应当划定的字段。例如,输入:
<newline><space><tab>foo<tab><tab>bar<space>
产生两个字段,foo 和 bar。
如果IFS 的值为空,则不进行字段拆分。
否则,以下规则将依次适用。术语“IFS 空白”用于表示 IFS 值中空白字符的任何序列(零个或多个实例)(例如,如果 IFS 包含
<space>
/<comma>
/<tab>
,则<space>
和<tab>
字符的任何序列都被视为 IFS 空白)。IFS 空白在输入的开头和结尾应被忽略。
非 IFS 空格的 IFS 字符输入中的每个出现,以及任何相邻的 IFS 空格,都应界定一个字段,如前所述。
非零长度的 IFS 空白应界定一个字段。
因此,每当 shell 扩展未加引号的参数、命令替换或算术扩展时,它都会根据 IFS 的设置方式将结果拆分为字段。
您可以在参数扩展的上下文中看到这一点,如下所示:
$ IFS=$' \t\n'
$ var='foo:bar'
$ printf '<%s>\n' $var
<foo:bar>
$ IFS=:
$ printf '<%s>\n' $var
<foo>
<bar>
$ printf '<%s>\n' "$var"
<foo:bar>
$ set -- foo bar baz
$ echo "$*"
foo:bar:baz
$ IFS=$' \t\n'
$ echo "$*"
foo bar baz
$
Run Code Online (Sandbox Code Playgroud)