1 特殊符号

特殊符号

符号 作用
’ ’ 单引号。在单引号中所有的特殊符号,如“$”(反引号)都没有特殊含义。单引号括起来的都是普通字符,会原样输出
“ ” 双引号。在双引号中特殊符号都没有特殊含义,但是“$”反引号(esc键下面)“\”是例外,拥有“调用变量的值”、“引用命令”和“转义符”的特殊含义。
$ 用于调用变量的值,如需要调用变量name的值时,需要用$name的方式得到变量的值。
${} 用于调用变量的值,如需要调用变量name的值时,需要用${name}的方式得到变量的值。
反引号 反引号。反引号括起来的内容是系统命令,在Bash中会先执行它。和()作用一样,不过推荐使用(),因为反引号非常容易看错。
$() 和反引号作用一样,用来引用系统命令。(推荐使用)
\ 转义符,跟在\之后的特殊符号将失去特殊含义,变为普通字符。如$将输出“$”符号,而不当做是变量引用。
() 用于一串命令执行时,()中的命令会在子Shell中运行
{} 用于一串命令执行时,{ }中的命令会在当前Shell中执行。也可以用于变量变形与替换。
[ ] 用于变量的测试。用于条件表达式
# 在Shell脚本中,#开头的行代表注释。
; 命令分隔符号

单引号、双引号、反引号

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
echo "$(echo hello)world"
[root@localhost ~]$ name=sc
#定义变量name 的值是sc(就是最正直的人,超哥我了!)
[root@localhost ~]$ echo '$name'
$name
#如果输出时使用单引号,则$name原封不动的输出
[root@localhost ~]$ echo "$name"
sc
#如果输出时使用双引号,则会输出变量name的值 sc

[root@localhost ~]$ echo `date`
2018年10月21日星期一18:16:33 CST
#反引号括起来的命令会正常执行
[root@localhost ~]$ echo '`date`'
`date`
#但是如果反引号命令被单引号括起来,那么这个命令不会执行,―date`会被当成普通字符输出
[root@localhost ~]$ echo "`date'"
2018年10月21日星期一18:14:21 CST
#如果是双引号括起来,那么这个命令又会正常执行

[root@localhost ~]$ echo ls
ls
#如果命令不用反引号包含,命令不会执行,而是直接输出
[root@localhost ~]$ echo `ls`
anaconda-ks.cfginstall.loginstall.log.syslog sh test testfile
#只有用反引号包括命令,这个命令才会执行
[root@localhost ~]$ echo $(date)
2018年10月21日星期一18:25:09 CST
#使用$(命令)的方式也是可以的

转义字符

1
2
3
4
5
6
7
8
\\
\a
\b
\f
\n
\r
\t
\v

正则表达式

元字符 描述 示例
\ 转义符,将特殊字符进行转义,忽略其特殊意义 a.b匹配a.b,但不能匹配ajb,.被转义为特殊意义
^ 匹配行首,awk中,^则是匹配字符串的开始 ^tux匹配以tux开头的行
$ 匹配行尾,awk中,$则是匹配字符串的结尾 tux$匹配以tux结尾的行
. 匹配除换行符\n之外的任意单个字符 ab.匹配abc或abd,不可匹配abcd或abde,只能匹配单字符
[ ] 匹配包含在[字符]之中的任意一个字符 coo[kl]可以匹配cook或cool
[^] 匹配[^字符]之外的任意一个字符 123[^45]不可以匹配1234或1235,1236、1237都可以
[-] 匹配[]中指定范围内的任意一个字符,要写成递增 [0-9]可以匹配1、2或3等其中任意一个数字
? 匹配之前的项1次或者0次 colou?r可以匹配color或者colour,不能匹配colouur
+ 匹配之前的项1次或者多次 sa-6+匹配sa-6、sa-666,不能匹配sa-
* 匹配之前的项0次或者多次 co*l匹配cl、col、cool、coool等
() 匹配表达式,创建一个用于匹配的子串 ma(tri)x?匹配max或maxtrix
{n} 匹配之前的项n次,n是可以为0的正整数 [0-9]{3}匹配任意一个三位数,可以扩展为[0-9][0-9][0-9]
{n,} 之前的项至少需要匹配n次 [0-9]{2,}匹配任意一个两位数或更多位数不支持{n,}{n,}{n,}
{n,m} 指定之前的项至少匹配n次,最多匹配m次,n<=m [0-9]{2,5}匹配从两位数到五位数之间的任意一个数字
` ` 交替匹配`

2 特殊字符

.(source)

.(点)与source命令一样,从文件中读取并执行命令,无论该文件是否都有可执行权限都能够正确的执行。且是在当前shell下执行,而不是产生一个子shell来执行(我们通常使用“./filename.sh”去执行一个文件是在当前shell下产生一个子shell去执行的)。所以在设置bash的环境的变量时,就必须用该命令或者source命令去执行设置的环境变量才会对当前shell生效,如下:

1
2
3
4
5
for i in /etc/profile.d/*.sh ; do
if [ -r "$i" ]; then
. $i
fi
done

:

: 该命令什么都不做,但执行后会返回一个正确的退出代码,即exit 0。比如在if语句中,then后面不想做任何操作,但是又不能空着,这时就可以使用“:”来解决,如下:

1
2
3
4
5
if [ "$i" -ne 1 ];then
:
else
echo "$i is not equal 1"
fi

()

() 将多个命令组合在一起执行,相当于一个命令组。
()是在产生的子shell下执行

{}

{}和()类似,也是将多个命令组合在一起。{}是在当前的shell下执行。这与前面讲到是使用”. filename.sh”和”./filename.sh”的区别一样。举一个很简单的例子:

1
2
3
4
5
6
7
# A=123
# (A=abc;echo $A);echo $A
abc
123
# { A=abc;echo $A; };echo $A
abc
abc
  • 从上面的示例可以看出,当在()中赋值的变量,影响的只是自身的子shell,而不能将该值赋给父shell,因为“父亲不能继承儿子”。而在{}中赋值的变量,因为就在当前的shell执行的,所以就能改变原来变量的值。

  • 注意:()里面两边可以不使用空格,{}里面两边必须使用空格,且最后一个命令也需要以“;”结尾,表示命令结束。

[] 与test命令一样,用于比较值以及检查文件类型。如下:

  1. [ “$A” = 123 ]:是字符串的测试,以测试 $A 是否为 1、2、3 这三个连续的”文字”。
  2. [ “$A” -eq 123 ]:是整数的测试,以测试 $A 是否等于”一百二十三”。
  3. [ -e “$A” ]:是关于文件的测试,以测试 123 这份”文件”是否存在。

[[]]

[[]]可以说是[]的“增强版”,它能够将多个test命令支持的测试组合起来,例如:

1
2
3
# [[ (-d "$HOME") && (-w "$HOME") ]] && echo echo "home is a writable directory"  

home is a writable directory

至于这两者的区别有位仁兄已经写的很清楚了,我将其整理一下:

1
2
3
4
5
6
7
8
数字测试: -eq -ne -lt -le -gt -ge,[[ ]]同 [ ]一致
文件测试: -r、-l、-w、-x、-f、-d、-s、-nt、-ot,[[ ]]同 [ ]一致
字符串测试: > < =(同==) != -n -z,不可使用“<=”和“>=”,[[ ]]同 [ ]

< >一致,但在[]中,>和<必须使用\进行转义,即\>和\<
逻辑测试: []为 -a -o ! [[ ]] 为&& || !
数学运算: [] 不可以使用 [[ ]]可以使用+ - */ %
组合: 均可用各自逻辑符号连接的数字(运算)测试、文件测试、字符测试

拿这两者对字符串的测试举一个例子,如下:

1
2
3
4
# [ a \> 1 ] && echo ture || echo false
ture
# [[ a > 1 ]] && echo ture || echo false
ture

字符串的比较是根据相应的ASCII码来比较的,所以a>1是成立的。如果有兴趣也可以思考一下为什么会出现下面的结果?

1
2
# [[ a > 1 ]] && echo ture || echo false
ture

(())

(())专门来做数值运算,如果表达式求值为 0,则设置退出状态为 1;如果求值为非 0 值,则设置为 0。不需要对 (( 和 )) 之间的操作符转义。算术只对整数进行。除 0 会产生错误,但不会产生溢出。可以执行 C 语言中常见的算术、逻辑和位操作。如下:

1
2
# ((i=1+99));echo $i
100

也能:

1
2
# i=99;((i++));echo $i
100

除此之外,也可以使用$(())直接进行数值运算,如下:

1
2
# echo $((2**3))
8

注意:使用 (( )) 时,不需要空格分隔各值和运算符,使用[][[ ]]时需要用空格分隔各值和运算符。

组合判断:

1
2
3
4
if [ $a -ne 0 ] && [ $b -lt 3 ] || [ $c -gt 5 ] 
then
#你在这里加其他操作
fi

|

管道表示将前一个命令的返回结果用作后一个命令的参数,管道的前后必须都是命令,管道是管理Linux十分有用的工具
$grep “test” file1.txt | wc -l

> >>

以新建的方式重定向,如果文件不存在就创建文件并将内容写入,如果文件存在就把文件清空再写入内容

以追加的方式重定向,如果文件不存在就创建文件并将内容写入,如果文件存在就在原文件后面写入内容

<

我们通常的操作就是文件,其实已经使用的输入重定向

2>

标准输入,标准输出,标准错误其实是三个完全不同的文件,虽然我们看起来标准输出和标准错误都输入到显示屏中显示,但是不能用输出重定向将错误重定向到其他文件
标准输入,标准输出,标准错误的文件描述符分别是0,1,2,这也是错误重定向2>的由来

&&

&&前的命令执行成功了就继续执行后面的命令

||

||前的命令执行失败了就去执行后面的命令

;

不论;前的命令执行成功与否都去执行后面的命令