Shell 脚本中有个变量叫 IFS(Internal Field Seprator) ,内部域分隔符。完整定义是The shell uses the value stored in IFS, which is the space, tab, and newline characters by default, to delimit words for the read and set commands, when parsing output from command substitution, and when performing variable substitution.
# 从下面的例子中可以看出,如果是用冒号引起来,表示这个变量不用IFS替换!!所以可以看到这个变量的"原始 # 值"。反之,如果不加引号,输出时会根据IFS的值来分割后合并输出! $* 是按照IFS中的第一个值来确定的!下 # 面这两个例子还有细微的差别! $ IFS=:; $ set x y z $ echo $* x y z $ echo"$*" x:y:z $ echo$@ x y z $ echo"$@" x y z # 上例 set 变量其实是3个参数,而下面这个例子实质是2个参数,即 set"x y z" 和 set x y z 是完全不同的。 $ set"x""y z" $ echo $* x y z $ echo"$*" x:y z $ echo$@ x y z $ echo"$@" x y z $ echo $* |od -b 0000000 170 040 171 040 172 012 0000006 $ echo"$*" |od -b 0000000 170 072 171 040 172 012 0000006 # 小结:$* 会根据 IFS 的不同来组合值,而 $@ 则会将值用" "来组合值!
Example 1: $ IFS=: $ var=ab::cd $ echo$var ab cd $ echo"$var" ab::cd # 解释下:x 的值是 "ab::cd",当进行到 echo$x 时,因为$符,所以会进行变量替换。Shell 根据 IFS 的 # 值将 x 分解为 ab ""cd,然后echo,插入空隔,ab[space]""[space]cd,忽略"",输出 ab cd 。
Example 2 : $ read a xy z $ echo$a xy z # 解释:这是 http://bbs.chinaunix.net/thread-207178-1-1.html 上的一个例子。此时IFS是默认值, # 本希望把所有的输入(包括空格)都放入变量a中,但是输出的a却把前面的空格给忽略了!!原因是:默认的 IFS # 会按space tab newline 来分割。这里需要注意的一点是,read 命令的实现过程,即在读入时已经替换了。解 # 决办法是在开头加上一句 IFS=";" ,这里必须加上双引号,因为分号有特殊含义。