被这本书骗了

被这本书骗了

[root@localhost 未命名文件夹]# ls
1 2.jpg  g g  test
[root@localhost 未命名文件夹]# ./test
test is a regular file
[root@localhost 未命名文件夹]# cat test
#!/bin/sh
for name in `ls` #注意不是''或者用$(ls)也正确 用*也正确
do
        if [ -f $name ]; then
                echo "$name is a regular file" #用''会显示$name
        elif [ -d $name ]; then
                echo "$name is a directory"
        fi
done
[root@localhost 未命名文件夹]#

代码源自

的第69页
很多错的地方,建议以后要做批阅工作的朋友拿来做练习
我还是在广州购书中心四楼买的,质量很差很弱小      


      
在实践中才会发现很多问题
纸上得来终觉浅,调试后的代码如下
复制内容到剪贴板
代码:
#!/bin/sh
for name in * #注意'ls'或者$(ls)或者`ls`都不正确 用*才正确
do
        if [ -f "$name" ]; then
                echo "$name is a regular file" #用''会显示$name
        elif [ -d "$name" ]; then
                echo "$name is a directory"
        fi
done
      
我来说一句,书中的这个例子是没有什么错误的,仅仅是不够严谨而已。

#!/bin/sh
for name in `ls`
do
        if [ -f $name ]; then
                echo "$name is a regular file"
        elif [ -d $name ]; then
                echo "$name is a directory"
        fi
done

====================================================
多数Linux发行版的ls命令并不是原始的ls命令,而是命令别名,我们可以运行 alias ls 就可以看到它实际上是原始的ls命令并已加上一个参数,不同的发行版和不同的使用者都可能有不同的习惯,也许在作者的机器上,他的 ls 也许是一行显示一个文件/文件夹的名称(比如他的alias ls=ls -1等等),所以在其机器上运行无误,但到了其他人的机器上,ls可能是一行显示多个文件/文件平的名称,此时就会出错了。

所以作者应该把`ls`写成`ls -1`,这样就严谨一些,在各个机器上均可正确运行;当然写成*的结果也一样。      
我试了一下,结果还是这样:

[root@localhost 未命名文件夹]# ls
1.jpg  3 3  4  g g  test.sh  未命名文件夹
[root@localhost 未命名文件夹]# ./test.sh
1.jpg is a regular file
4 is a regular file
test.sh is a regular file
未命名文件夹 is a directory
[root@localhost 未命名文件夹]# cat test.sh
#!/bin/sh
for name in `ls -1`
do
        if [ -f "$name" ]; then
                echo "$name is a regular file"
        elif [ -d "$name" ]; then
                echo "$name is a directory"
        fi
done
[root@localhost 未命名文件夹]#



      
我的总结:

1.
错误代码:
find | while read name
do
    echo "$name"
done
严格的讲, find | read 模式也是有问题的, read 会对反斜杠 \ 有特殊处理
find | sed -e 's/\\/\\\\/g' | while read name
do
    echo "$name"
done
这样的代码才不会一遇到输入字符串的空格就进入do...done且处理了read的特殊情况
2.
错误代码:
echo $name
正确代码:
echo "$name"
echo "$name" 跟 echo $name 还是有区别的. 比如 name 中有两个连续空格的时候 
3.
for name in *
do
    echo $name
done
这样的代码不会一遇到输入字符串的空格就进入do...done
4.
for name in `ls`
do
    echo $name
done
这样的代码会一遇到输入字符串的空格就进入do...done
5.
dir=`pwd`
echo $dir
即使`pwd`输出中有空格,dir也会归入其中,成为一个完整的字符串
6.
错误代码:
if [ -e $test ] ; then
    echo "hoho"
fi
正确代码:
if [ -e "$test" ] ; then
    echo "hoho"
fi
7.
错误代码:
file $name
cat $name
rm $test
basename $dir
cp "have a test" $installdir
正确代码:
file "$name"
cat "$name"
rm "$test"
basename "dir"
cp "have a test" "$installdir"
8.
正确代码:
output="have a test"
echo "just" > $output

另送一个bash编程常见错误的总结网址:
http://tech.idv2.com/2008/01/09/bash-pitfalls/

结论:
没有特殊应用的话
for name in `ls`是错误的(for name in 'ls'也是错)
可以写成
for name in *
do
    ....
done

ls | sed -e 's/\\/\\\\/g' | while read name
do
    ....
done

      
另送一个bash编程常见错误的总结网址:
http://tech.idv2.com/2008/01/09/bash-pitfalls/

      
买书一定看书评,不然话,后悔人      
尽信书不如无书       
总结的好详细哦。受教了。