Lon*_*ner 12 bash shell for-loop ifs
这是我在文件中命名的第一个脚本foo.sh.
IFS=:
for i in foo:bar:baz
do
echo $i
done
Run Code Online (Sandbox Code Playgroud)
这会产生以下输出.
$ bash foo.sh
foo bar baz
Run Code Online (Sandbox Code Playgroud)
这是我的第二个脚本.
IFS=:
for i in foo:bar:baz
do
unset IFS
echo $i
done
Run Code Online (Sandbox Code Playgroud)
这会产生以下输出.
$ bash foo.sh
foo:bar:baz
Run Code Online (Sandbox Code Playgroud)
这是我的第三个脚本.
IFS=:
var=foo:bar:baz
for i in $var
do
echo $i
done
Run Code Online (Sandbox Code Playgroud)
这会产生以下输出.
$ bash foo.sh
foo
bar
baz
Run Code Online (Sandbox Code Playgroud)
为什么三种情况下的输出都不同?你能解释一下IFS解释背后的规则以及导致这种不同输出的命令吗?
Sto*_*ica 15
我发现这是一个非常有趣的实验.谢谢你.
要了解发生了什么,相关部分man bash是这样的:
Word Splitting
The shell scans the results of parameter expansion, command substitu-
tion, and arithmetic expansion that did not occur within double quotes
for word splitting.
关键是"......的结果"部分,而且非常微妙.也就是说,单词拆分发生在某些操作的结果上,如下所示:参数扩展的结果,命令替换的结果,等等.不对字符串文字执行单词拆分,例如foo:bar:baz.
让我们看看这个逻辑在你的例子中是如何发挥作用的.
IFS=:
for i in foo:bar:baz
do
echo $i
done
Run Code Online (Sandbox Code Playgroud)
这会产生以下输出:
foo bar baz
无字拆分对文字进行foo:bar:baz,所以也无所谓什么是价值IFS,只要for循环而言.
字符拆分是在参数扩展后执行的值$i,因此foo:bar:baz被拆分为3个字,并传递给echo,因此输出为foo bar baz.
IFS=:
for i in foo:bar:baz
do
unset IFS
echo $i
done
Run Code Online (Sandbox Code Playgroud)
这会产生以下输出:
foo:bar:baz
再次,无字拆分对文字进行foo:bar:baz,所以也无所谓什么是价值IFS,只要for循环而言.
字符拆分是在参数扩展后执行的值$i,但由于IFS未设置,其默认值用于执行拆分,即<space><tab><newline>.但由于foo:bar:baz不包含任何这些,它保持不变,因此输出是foo:bar:baz.
IFS=:
var=foo:bar:baz
for i in $var
do
echo $i
done
Run Code Online (Sandbox Code Playgroud)
这会产生以下输出:
foo bar baz
的参数膨胀后$var,词的拆分是使用的值来进行IFS,因此for具有3个值来遍历,foo,bar,和baz.这里的行为echo是微不足道的,输出是每行一个字.
底线是:不对文字值执行单词拆分.单词拆分仅对某些操作的结果执行.
这并不奇怪.字符串文字很像用双引号括起来的表达式,你不会期望分词"...".