在计算机科学中,Shell俗称壳(用来区别于核),是指“提供使用者使用界面”的软件(命令解析器)。它类似于DOS下的command.com。它接收用户命令,然后调用相应的应用程序。同时它又是一种程序设计语言。作为命令语言,它交互式解释和执行用户输入的命令或者自动地解释和执行预先设定好的一连串的命令;作为程序设计语言,它定义了各种变量和参数,并提供了许多在高阶语言中才具有的控制结构,包括循环和分支。shell是一种解释型编程语言,这些都不重要,重要的是怎么使用它。


一、 执行shell脚本的方法

1. 输入重定向到shell脚本,具体来讲是利用输入重定向机制,让shell解释器顺序读取每一行脚本命令,进行执行,使用原型为bash>脚本文件名,例如:bash>test.sh

2. 类似于方法1,不过它是以脚本文件名为参数来执行的,原型:bash test.sh 。

3. 将脚本文件设置成可执行文件,直接调用执行,./test.sh 。(用chmod +x test.sh将脚本文件加上可执行权限)

二、shell的基本语法

赋值一般采用以下形式:变量名=字符串

1. “=”号两边是不能有空格的,不然会出错的。

2. 若赋值语句中,“=”后面没有任何内容,则该变量为一个空字符串,若只声明而没赋值,则该变量默认也是一个空字符串。

3. 若一个变量中含有空格、制表符、换行符,则要用双引号括起来,不然会出错。

4. 在shell程序文件中,如果想引用已经定义的变量,一般要在变量名前加“$”符号,这个符号含义是告诉shell,后面是一个变量。

5. 单引号(‘…’):单引号也称为强引用,引用所有内容。在单引号中,没有字符拥有特殊含义。

6. 双引号(“…”):双引号也称为弱引用,除了3个元字符$(美元符号)、`(反引号)和\(反斜线)外引用所有内容。在双引号中,这3个字符还保留它们各自的特殊含义。

7. 反引号(`…`):命令替换,命令替换允许在一条命令中嵌入一条命令。shell首先执行嵌入的命令,并且用输出替换该命令。然后shell再执行整个命令。

8. 在shell变量引用中,一个变量与一个长字符串的组合,如果当前变量处在字符串的最后,可以利用直接引用的方式;如果处在中间或开头的位置,则可以用花括号将变量名包含起来。如下:
程序:

1
2
3
4
5
#!/bin/bash
address=beijing
echo $address
echo ${address}test
echo test$address

输出:

1
2
3
beijing
beijingtest
testbeijing

三、shell中的通配符(用于模式匹配)

1. “*”符号

“*”符号用于匹配字符串中0次或多次出现的字符,如:s*可以匹配shell、shanghai等。在使用“*”符号时要注意一点,在匹配文件名与路径名时,“.”符号与“\”必须显示匹配,如:*test不能匹配“.httest”文件,而要用“.*test”来匹配,同时“/home/test”需要用”/*/test”来匹配。

2. “?”符号

“?”符号仅匹配对应位置的一个字符。如:m?ke可匹配”mike”、”make”等,但不能匹配”mooke”。

3. “[]“符号

“[]“称号的作用是匹配该字符组所限定范围内的任何一个字符,方括号中的字符可以由直接级出的字符组成,如:[adehk];也可以由表示限定范围的起始字符和终止字符及中间的连接字符”-”组成。如:[a-zA-H]、[0-9]等。

4. “!”符号

“!”符号是与”[]“符号配合使用的,”!”的作用是匹配不在方括号中列出的字符。例如:t[!a-h]st,则可表示tyst、t9st,但不能表示test。

四、shell中的输入

shell中输入是由函数read实现,原型为:read 变量1 [变量2]

利用read函数可以交互地为变量赋值,当然也可以通过制表符或空格为多变量赋值,说明如下:

1. 如果变量个数多于输入串中字符串个数,则依次赋值,剩下变量取空值。

2. 如果变量个数等于输入串中字符串个数,则一一对应赋值。

3. 如果变量个数少于输入串中字符串个数,刚除依次赋值外,最后一个变量接纳剩下的字符串。

例如:

1
2
3
4
5
#!/bin/bash
echo "input your name and age:"
read name age
echo "your name is: "$name
echo "your age is: "$age

如果你输入Jim 15 则输出:

1
2
3
input your name and age:
your name is: Jim
your age is: 15

五、shell中的输出

shell中输出是由echo函数实现的,echo可直接输出其后面所跟变量的值或直接输出其后面的字符串。echo函数后面以空格隔开,以换行符终止。如果数据之间要保留多个空格,则要用双引号把它们括起来以便shell对它们进行正确的操作。另:echo函数还定义了一组转义字符,在使用转义字符时要加入”-e”选项。其转义字符如下:

“\a” :响铃报警,”\b” :后退一字符,”\f” :换页,”\n” :显示换行,”\t” :制表符,”\v” :垂直制表符,”\r” :回车符,”\\” :反斜线。
例如:

1
2
3
4
5
6
7
#!/bin/bash
echo -e hello,'\n'world!
echo hello,'\n'world!
echo '-e' hello,'\n'world!
echo -e hello,"\n"world!
echo -e hello,\nworld!
echo hello,\nworld!

输出:

1
2
3
4
5
6
7
8
9
hello,
world!
hello,\nworld!
hello,
world!
hello,
world!
hello,nworld!
hello,nworld!

六、shell中的数组

shell支持一维数组,但并不限定数组大小,数组下标从0开始。

在操作数组时,取值方式是:${数组名[下标]} ;赋值方式是:数组名[下标]=值 (为单个数组元素赋值);如果要对整个数组的所有元素赋值,可以采用:数组名=(值1,值2,值3,…),值与值之间要用空格隔开。

遍历数组除用循环外还可用:“数组名[*]”或“数组名[@]”,例如:

1
2
3
4
5
6
7
8
9
10
11
12
#!/bin/bash
array1[0]=beijing
array1[1]=shanghai
array2=(guangzhou,shenzhen,chengdu)
echo "\${array1[0]} = " ${array1[0]}
echo "\$array1[1] = "$array1[1]
echo "\${array1[*]} = "${array1[*]}
echo "\$array1 = "$array1
echo "\${array2[*]} = "${array2[*]}
echo "\${array2[@]} = "${array2[@]}
echo "\$array2 = "$array2
echo "\$array2[1] = "$array2[1]

输出:

1
2
3
4
5
6
7
8
${array1[0]} =  beijing
$array1[1] = beijing[1]
${array1[*]} = beijing shanghai
$array1 = beijing
${array2[*]} = guangzhou,shenzhen,chengdu
${array2[@]} = guangzhou,shenzhen,chengdu
$array2 = guangzhou,shenzhen,chengdu
$array2[1] = guangzhou,shenzhen,chengdu[1]

注:数组的赋值与输出有点麻烦。
对于数组修改操作,可以再对其重新赋值;但如果要删除一个已经赋值后的元素则需要借助一个外部命令:unset,如:unset array[0]可清空下标为0的元素,此时数组大小减一;unset array[@]可以清空整个数组元素所有元素。例如:

1
2
3
4
5
6
#!/bin/bash
address=(beijing,shanghai,shandong)
address[0]=nanjing
echo ${address[*]}
unset address[0]
echo ${address[*]}

输出:

1
2
beijing shanghai shandong
shanghai shandong

注:关于数组输入与输出规则比较多,得多练习掌握。