Shell编程 Bash引号的那点事
先了解下,在bash脚本中,有三种引号
1.单引号'
2.双引号"
3.反引号`
单引号
两个单引号包围起来的字符串就是普通的字符串,它将保留原始的字面意思.
双引号
两个双引号包围起来的字符串,部分特殊字符将起到它们的作用.
这些特殊字符有:美元符$,反斜杠\,反引号, 感叹号!.
反引号
两个反引号包围起来的字符串,将作为命令来运行,
执行的输出结果作为该反引号的内容,称为命令替换,
它有另一种更好的写法:$(command)
我们来看几个例子,更直接的了解这三种引号的特性.
1.美元符$在单、双引号中的表现:在双引号中的$,将发生变量引用,而在单引号中的$,将保留它的字面意思
igi@gentoo~$echo'$HOME' $HOME igi@gentoo~$echo"$HOME" /home/igi
注:HOME为内部变量
2.反斜杠\在单、双引号中的表现:在双引号中的\,将转义它后面的字符,使其具有特殊意义或者失去原来的特殊意义,在单引号中的\,将保留它的字面意思
igi@gentoo~$echo'\$HOME' \$HOME igi@gentoo~$echo"\$HOME" $HOME
注:双引号中的\,后面跟着$,这里发生了转义,使得$失去特殊意义,变成普通字符.
3.反引号与其他两种引号的不同:反引号包围起来的字符串将被运行,取其结果
igi@gentoo~$echo'date' date igi@gentoo~$echo"date" date igi@gentoo~$echo`date` FriDec318:34:09CST2010
注:在反引号中的date被当成命令执行,包含的正是命令的输出信息
了解了他们的不同,我们来聊一聊常见的问题
1.把反引号`写成单引号'
不得不说,它们长得确实很像,个别书的印刷字体区别度不高或者印刷质量不过关,导致了很多新手认错,常把反引号`写成单引号'。如果你不知道反引号在哪,请看看Esc键下面的那个按键,那个就是反引号。当然也不排除有些人看书不注意,这也是常有的事。只要我们明白了反引号与单引号作用的区别,什么时候要用单引号,什么时候要用反引号就一清二楚了。当你需要一个字符串时,使用单引号;而当你需要捕捉命令的输出时,请用反引号。
2.总是忘了加双引号
双引号不总是多余的,被它包围的数据变得很安全,不至于被bash切开对待。
igi@gentoo~$seq3 1 2 3 igi@gentoo~$echo`seq3` 123 igi@gentoo~$echo"`seq3`" 1 2 3
注:seq输出的是包含换行的信息,但echo`seq3`却丢失了换行符,因为bash在解析时认为`seq3`的输出结果是3个独立的字符,解析后与echo123相同(这个过程,bash做了很多工作,有兴趣的可以了解下bash解析顺序);而echo“`seq3`”时,bash把`seq3`的输出结果当成一个整体对待(因为它被双引号包围),所以输出的结果不会被bash拆分对待,换行符得以保留。所以,当你需要保留变量或者命令替换的完整信息,特别是换行符时,请记得给它们戴上双引号作保险,时刻加个双引号是个好习惯(为什么不是单引号呢?前面解释了,单引号里面没有魔法,变量也变不了了,命令替换也替换不了了)。再次提醒:“$var”,“`command`”,都比$var,`command`安全得多,很多情况下,前面的才是你要的结果,除非你知道你在做什么,否则不要轻易省略双引号。
3.引号嵌套总是混乱的
引号中包含其他引号,只要能理解单引号和双引号中字符的表现,就不难掌握
igi@gentoo~$echo"abc\"abc" abc"abc igi@gentoo~$echo"abc\'abc" abc'abc igi@gentoo~$echo"abc\`abc" abc`abc
如你所见,双引号中加入其他引号很容易,你只需要用反斜杠\转义你要添加的引号(双引号中加单引号可以不用转义)。那么单引号中是否如此简单?
igi@gentoo~$echo'abc"abc' abc"abc igi@gentoo~$echo'abc`abc' abc`abc
到这里,确实很简单,单引号中都是普通字符,所以完全不需要转义,如果加了反斜杠\,那么反斜杠依然是它自己,直接打印出来。
igi@gentoo~$echo'abc\"\`abc' abc\"\`abc
问题来了,单引号中如何包含单引号?这个时候,反斜杠\也是无用的,如果直接写单引号,那么bash会认为引号还没结束。好吧,如果你不幸碰到这样的问题,还是有办法解决的
igi@gentoo~$echo$'abc\'abc' abc'abc igi@gentoo~$echo-e'abc\x27abc' abc'abc igi@gentoo~$echo'abc'\''abc' abc'abc
第一种方法是bash特有的,$'string'之间到反斜杠都将转义字符,第二种方法,通过单引号的ASCII码来打印单引号,而第三种方法,则是通过截断命令,在中间插入单引号来实现。一般用第一种方法是最优雅的。
最后:希望能更多的人喜欢Bash,使用Bash。