Shell编程 Bash引号与空格那点事

转载自 https://www.jb51.net/article/60329.htm

空格太坑啊,我第一次打个99乘法表疯狂错,不忍心看到后面还有人还因为经常这么曲折的过来

先了解下,在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\`  
Fri Dec 3 18:34:09 CST 2010  

注: 在反引号中的date被当成命令执行,包含的正是命令的输出信息

了解了他们的不同,我们来聊一聊常见的问题

1. 把反引号` 写 成单引号’

不得不说,它们长得确实很像,个别书的印刷字体区别度不高或者印刷质量不过关, 导致了很多新手认错,常把反引号`写成单引号’。如果你不知道反引号在哪,请看看Esc键下面的那个按键, 那个就是反引号。当然也不排除有些人看书不注意,这也是常有的事。只要我们明白了反引号与单引号作用的区别,什么时候要用单引号,什么时候要用反引号就一 清二楚了。当你需要一个字符串时,使用单引号; 而当你需要捕捉命令的输出时,请用反引号。

2. 总是忘了加双引号
双引号不总是多余的,被它包围的数据变得很安全,不至于被bash切开对待。

复制代码 代码如下:

igi@gentoo ~ $ seq 3  
1  
2  
3  
igi@gentoo ~ $ echo \`seq 3\`  
1 2 3  
igi@gentoo ~ $ echo "\`seq 3\`"  
1  
2  
3  

注: seq输出的是包含换行的信息,但echo `seq 3` 却丢失了换行符,因为bash在解析时认为`seq 3`的输出结果是3个独立的字符,解析后与echo 1 2 3相同(这个过程,bash做了很多工作,有兴趣的可以了解下bash解析顺序); 而echo “`seq 3`”时,bash把`seq 3`的输出结果当成一个整体对待(因为它被双引号包围),所以输出的结果不会被bash拆分对待,换行符得以保留。所以,当你需要保留变量或者命令替换的 完整信息, 特别是换行符时,请记得给它们戴上双引号作保险,时刻加个双引号是个好习惯(为什么不是单引号呢?前面解释了,单引号里面没有魔法,变量也变不了了,命令 替换也替换不了了)。再次提醒: “KaTeX parse error: Can't use function '\`' in math mode at position 8: 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  

Notice:
1.定义变量时, =号的两边不可以留空格.

eg:
gender=femal————right
gender =femal———–wrong
gender= femal———–wrong

2.条件测试语句 [ 符号的两边都要留空格.

eg:
if [ $gender = femal ]; then——-right.
echo “you are femal”;
fi
if[ g e n d e r . . . w r o n g i f [ gender...-----------------------wrong if [ gender…----------------------wrong.

3.条件测试的内容,如果是字符串比较的话, 比较符号两边要留空格!

eg:
if [ $gender = femal ]; then——-right.
if [ $gender= femal ]; then——–wrong.
if [ $gender=femal ]; then———wrong.

4.命令和其后的参数或对象之间一定要有空格

if [ -x"~/Workspace/shell/a.sh" ];then
只有 -x 后有空格才表示紧跟其后的字符串是否指向一个可执行的文件名,否则就成了测试 -x"~/Workspace/shell/a.sh" 这个字符串是不是空。

5.取变量值的符号’$'和后边的变量或括号不能有空格

猜你喜欢

转载自blog.csdn.net/qq_42137895/article/details/85381842