注册 登录
编程论坛 Linux教室

bash 中 read 的问题

pangding 发布于 2011-02-28 20:14, 1280 次点击
前几天写脚本的时候,用 read 处理管线的上下文时发现了一个挺令我意想不到的 BUG,虽然后来用 sed 代替了。不过还是想弄清楚是怎么回事。

脚本和結果如下:
$ cat shtest.sh
#! /bin/bash

while read abc ; do
    printf "%s, %s\n" $abc $abc
done <<- EOF
    abc def ghi
    jkl mno pqr
EOF
$ ./shtest.sh
abc, def
ghi, abc
def, ghi
jkl, mno
pqr, jkl
mno, pqr
$

我预期的結果应该是这个样子:
abc def ghi, abc def ghi
jkl mno pqr, jkl mno pqr

差距还是比较大的。为什么会这样?


[ 本帖最后由 pangding 于 2011-2-28 20:16 编辑 ]
6 回复
#2
pangding2011-03-02 11:01
嗨……只是输出比较诡异,混淆了视听。其实原因很简单……


printf "%s, %s" $abc $abc
改成
printf "%s, %s" "$abc" "$abc"
就行。

初学者的惯常错误,呵呵~
#3
ansic2011-03-03 11:29
echo $abc $abc
#4
vfdff2011-03-08 23:45
"$abc" 和 $abc 有什么区别?
#5
pangding2011-03-15 20:37
回复 4楼 vfdff
空格有对 bash 来说有语法意义。
bash 先扩展变量的值,然后再传执行命令。像我第一次写的,扩展之后就变成:
printf "%s, %s\n" abc def ghi abc def ghi
printf 看见了六个,参数。它会执行三次 "%s, %s\n" ,直到把给它的参数都用完,输出:
abc, def
ghi, abc
def, ghi
加引号之后,扩展会变成:
printf "%s, %s\n" "abc def ghi" "abc def ghi"
引号里面的东西,bash 不尝试解释。(当然有例外,详见文档中 quoting 一节的说明)
这样 printf 眼中只有两个参数。输出就会如我预期的一样。
#6
vfdff2011-03-16 23:20
printf 看见了六个,参数。它会执行三次 "%s, %s\n"
这个是printf函数自己实现的一种机制?
#7
pangding2011-03-18 19:40
回复 6楼 vfdff
bash 的文档也没詳細说明这种行为,不过实际用的时候是这样的。
而且 printf(1) 也有类似的行为。

我觉得不推荐使用这种特性吧。确实挺容易混淆人的。
1