LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1241|回复: 6

shell的设计不太严格吗?

[复制链接]
发表于 2008-4-23 12:58:04 | 显示全部楼层 |阅读模式
shell编程越深入感觉,不可预知的事情感觉也越多,是不是shell的实现不太严格啊?
在没有执行的前提下,你想看出脚本程序的结果,比较难:
1、echo `echo \\\\\\\n`打印 \\n
2、echo "$(ls -l)"和echo $(ls -l)前者会换行输出
3、if [ 0 ] ;then
   echo "1"
   else
   echo "2"
fi
这段打印 1
if [ 1 ] ;then
   echo "1"
   else
   echo "2"
fi
这段也打印 1
if [ -1 ] ;then
   echo "1"
   else
   echo "2"
fi
这段也打印 1

if [ 0=1 -a 1=2 ] ;then
   echo "1"
   else
   echo "2"
fi
这段打印 2
发表于 2008-4-23 21:50:45 | 显示全部楼层
别人看不懂的奇妙的程序其实没什么价值
回复 支持 反对

使用道具 举报

发表于 2008-4-23 22:42:50 | 显示全部楼层
有什么不严谨,你说的这些都是很正常的行为,只是你还不够深入了解。
sh家族的shell已经被标准化,如果有任何ambiguous的地方,就别用这些特性——完全不会影响你写出本身而言可移植性良好的script。

你没理解单引号,双引号,和无引号时,shell对命令行参数,特别是反斜线的解析的微妙差别;
你也许也不知道echo有个“-e”选项用来打开对C风格转义序列的解释;
你也许不知道shell有个环境变量叫IFS,并且你肯定不知道它的作用;
你学过C编程,至少了解在C中整数0是false,non-0是true,自然就认为shell也一样,但是,错!你也许不知道一点: if 关键字测试的是其后命令是否执行成功,成功则执行分支,失败则执行另一分支或不执行,而“[”是shell的一个内部命令,并且必须匹配一直“]”作为最后一个命令行参数,它根据括起来的条件表达式返回表示成功或者失败的返回值,并且对于字符串,除非为空字符串,否则就返回0,表示命令执行成功。记住shell中字符串是第一类型。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2008-4-24 13:37:59 | 显示全部楼层
的确,第三个问题是我的概念不清,我后来整出来了if结构的一些非主流的规则,供大家参考:
在if结构中,如果测试条件中的命令或者相关的条件发生错误,那么标准输出将先输出错误信息,接
着shell将假定测试条件为假,程序流从而进入else或者elif结构以继续执行。

if $var
then
echo "1"
else
echo "2"
fi
var没有初始化时,执行echo "1";初始化了,又分两种情况,1、当$var最终扩展为某个shell命令时
那么执行结果将是先执行该命令,再根据执行结果进行if结构的分支选择;2、当$var扩展仅仅为某个
无意义的符号时,那么执行将发生错误。

if
then
echo "1"
else
echo "2"
fi
会发生解释错误 ,if后面什么都没有。(我本想模拟上面var未初始化的情形,但是通不过语法检测)

if []
then
echo "1"
else
echo "2"
fi
打印2

if [ xyz ]
then
echo 1
else
echo 2
fi
其中xyz是一个任意的字符串,可以是0,1,-1甚至是0=1等没有IFS分隔符的字符串。对于此类字符串,[]将返回真,也即0,程序流因此转向真的方向。当然这种形式是可扩展的如:if [ xyz -a 0 != 2 ],前面为真,后面也为真,所以[]返回真。xyz这种字符串不能含有IFS分隔符,否则产生错误。避免此类错误的方法是使用“”。

if [ $var ]
then
echo "1"
else
echo "2"
fi
var没有初始化时,执行echo "2",此种情形同if []。
如果$var已经初始化,又分两种情况,1、当变量扩展成有IFS分隔符时,那么测试条件将发生错误,标准输出
输出错误信息,并转向else或elif结构。若想避免这种错误情况的发生,可以使用“”,如if [ "$var" ]。但是要注意的是var变量再声明时也应加上“”,如:var="ls -l -a -r -R"。2、如果变量var没有扩展成含有IFS分隔符的字符串时,容易想象,那么其执行的结果与if [ xyz ](见前面)必定是相同的。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2008-4-24 13:59:12 | 显示全部楼层
jockey版主,感谢你的回复,针对我提出的前两个问题,希望你能够给予直接的解答。
关于你提到的echo 的-e参数,我是知道的,我是故意不用该参数的,如果使用的话,我想标准输出上打印的应该是\n吧。如你所说,There is no ambiguity in the shell . 但是为什么不加-e的echo打印的却是\\n呢?
还有,IFS分隔符虽然我用的不多,而且没有修改过,但是对于IFS还是了解一些的。我想你谈到IFS对应的是回答我的第二个问题。我机器里的IFS是默认值,可是为什么“”中的ls -l的输出就会换行呢?难道没有“”,换行符就失去作用了吗?
我上个礼拜才开始学习shell,对shell编程仅有一个大体的了解,关于你说的:“你没理解单引号,双引号,和无引号时,shell对命令行参数,特别是反斜线的解析的微妙差别”,我觉得特别正确,现在特别想搞清楚他们间的详细差别,我也查过很多书,但是讲的都是很基础的内容,希望你能给出一个详细的介绍。
先谢过了。
回复 支持 反对

使用道具 举报

发表于 2008-4-24 20:55:00 | 显示全部楼层
  1.        Command substitution allows the output of a command to replace the com-
  2.        mand name.  There are two forms:
  3.               $(command)
  4.        or
  5.               `command`
  6.        Bash performs the expansion by executing command and replacing the com-
  7.        mand substitution with the standard output of  the  command,  with  any
  8.        trailing newlines deleted.  Embedded newlines are not deleted, but they
  9.        may be removed during word splitting.  The command  substitution  $(cat
  10.        file) can be replaced by the equivalent but faster $(< file).
  11.        When  the  old-style  backquote form of substitution is used, backslash
  12.        retains its literal meaning except when followed by $, `,  or  \.   The
  13.        first backquote not preceded by a backslash terminates the command sub-
  14.        stitution.  When using the $(command) form, all characters between  the
  15.        parentheses make up the command; none are treated specially.
复制代码
重要的是最后一段,所以
  1. $ echo `echo \\\\\\\n`
复制代码
对backslash做出的解释是这个:
  1. $ echo `echo '\\\\n'`
复制代码
相当于
  1. $ echo \\\\n
复制代码
相当于
  1. $ echo '\\n'
复制代码
此时输出自然是
  1. \\n
复制代码
第二个问题更好解释,IFS默认值是空格、制表符和新行符三者的序列,其作用之一是用来对命令行分词。如果不将参数用双引号括起来,当
  1. $ echo $(ls -l)
复制代码
被扩展后,原来 ls -l 输出中的newline全部被看成是分词用的词间分割符,也就丢失了;当
  1. $ echo "$(ls -l)"
复制代码
被扩展后,由于双引号的存在,newline被全部保留,并且送入echo输出。
回复 支持 反对

使用道具 举报

发表于 2008-5-5 17:22:11 | 显示全部楼层
领教了,这些好像确实需要仔细的研究。
版主厉害。佩服各位精益求精的精神。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表