作者:海鹰
此教程讲述如何编写shell脚本
版权所有,未经允许,请勿随意转载。
1. 使用shell
Linux提供多个shell解释器给用户选择。
登录后进入用户指定的shell
编辑/etc/passwd文件,找到需要修改shell的用户名,修改行末尾的shell程序。
使用chsh命令改变用户登录后进入的shell
临时改变正在使用的shell
2. bash程序设计
- shell程序就是把用户输入的shell命令按照控制结构组织到一个文本文件中,批量地交给shell去执行。
- shell程序是通过shell命令解释器执行的,不生成二进制的可执行代码。
- shell程序又称shell脚本程序,不同的shell解释器编制脚本程序的语法不完全相同。
#! /bin/bash
- 程序的第1行指定了采取的shell脚本解释器。它由“#!”开始,其后是解释器的路径。
- 如果采用其他解释器,可以用相应的路径替换/bin/bash。
注释
shell脚本中采用#作为注释符号。以#开始的注释只在本行起作用,多行注释需要在每行之前都加上#号。
其它
- 将文件保存为.sh文件类型。
- 需要赋予文件可执行权限:chmod +x HelloWorld.sh。
- echo $?,输出变量“?”的值,“$?”是检查前驱命令返回值的常用方法。
3. 变量
bash脚本语言是一种弱类型的脚本语言。所谓弱类型脚本语言,是指这种语言对类型的要求不严格,同一个变量随着使用场合的不同,可以存储不同类型的数据。
赋值
变量=值
注意:等号两侧不能有空格
比如:a=”hello”
引用
引用一个变量可以在变量名前加一个$
比如:echo “$a world”引用变量还可以采用:${变量名}
比如:echo “${a} world”第二种引用方式还有以下几种常用的扩展用法
${variable: -value}:如果变量variable存在,则返回variable的值,否则返回value。
${variable: =value}:如果变量variable存在,则返回variable的值,否则,先将value赋给变量variable,然后返回值value。
${variable: +value}:如果变量variable存在,则返回值value,否则返回控制。
${variable:?value}:如果变量variable存在,则返回variable的值,否则将value送到标准错误输出显示并退出shell程序,这里的value通常为一个错误提示消息。
${variable: offset[: length]}:返回从变量variable的第(offset+1)个字符开始的、长度为length的子串,如果中括号内的部分省略,则返回其后的所有子串。要指明表达式是一个运算式,可以使用expr命令和let命令。
expr
格式:expr arg,arg代表一个表达式,表达式是一个由运算符和操作数连接起来的字符串。
expr命令根据运算符的类型来判断操作数的类型,另外,操作数和运算符之间要用空白字符隔开,否则,expr计算错误。
在表达式中有通配符(如“ * ”)时,要采用转义字符“\”或者引号(单引号或双引号)。
比如:
expr 3 * 2 错误
expr 3 \* 2 正确
expr 3 ‘*‘ 2 正确
expr 3 “*“ 2 正确当表达式比较复杂、含有不同优先级的运算符时,最好采用把复杂的表达式拆分成几个简单的表达式的方法。
比如:
s = `expr 2 + 3`
expr $s \* 4
或 expr `expr 2 + 3` \* 4
注意,这里使用了反向引号(`)
let
格式:let arg1 [arg2…],其中,中括号表示可以有多个参数,argN(N=1,2,3……)为表达式。每个表达式内的运算符和操作数之间不必用空格分开。
let命令可以一次对多个表达式进行计算。
当表达式中含有<、>、&、|等特殊符号时,需要用转义字符“\”或者引号(单引号或双引号)放在特殊符号前面。
示例
let s = (2+3)*4
4. 条件判断
在shell程序中,0表示真,非0表示假,这一点与C语言恰恰相反。
在bash中,对条件进行判断的命令是test和中括号[ ],二者是等价的。
使用格式是:
test condition
或
[ condition ]利用中括号[ ]进行判断时,左、右中括号和判断条件之间要用空格分隔开。
condition为需要判断的条件,可以是:
文件属性的测试,包括文件类型、文件访问权限等
字符串属性的测试,包括字符串长度、内容等
整数关系的测试,包括比较大小、相等判断等逻辑运算
逻辑与-a:condition1 -a condition2
逻辑或-o:condition1 -o condition2
逻辑非!:!condition
测试文件属性
常用文件属性判断
-f fn:fn是否存在且为普通文件
-b fn:fn是否存在且为块设备
-e fn:fn是否存在
-d fn:fn是否存在且为目录
-r fn:fn是否存在且可读
-w fn:fn是否存在且可写
-x fn:fn是否存在且可执行
-O fn:fn是否存在且被当前用户拥有
-L fn:fn是否存在且为符号链接示例
1
2
3
4
5
6
7
8
9
10
11
12# 文件是否存在且可写
[root@localhost shell]# test -w test.sh
[root@localhost shell]# echo $?
0
# 文件是否为目录,且可写
[root@localhost shell]# test -d test.sh -a -w test.sh
[root@localhost shell]# echo $?
1
# 文件是否可读,并且可写
[root@localhost shell]# test -r test.sh -a -w test.sh
[root@localhost shell]# echo $?
0
测试字符串属性
- 常用字符串属性条件判断
string_1 = string_2:string_1和string_2是否相等
string_1 != string_2:string_1和string_2是否不相等
-z string:string的长度是否为0
-n string:string的长度是否不为0
string:等同于-n string
测试整数关系
- 常用整数关系条件判断
num_1 -eq num_2:num_1是否等于num_2
num_1 -ne num_2:num_1是否不等于num_2
num_1 -gt num_2:num_1是否大于num_2
num_1 -lt num_2:num_1是否小于num_2
num_1 -ge num_2:num_1是否大于等于num_2
num_1 -le num_2:num_1是否小于等于num_2
5. 控制结构
if
语法
1
2
3
4
5
6
7
8
9if 条件1
then
命令
[elif 条件2
then
命令]
[else
命令]
fi当要求if的判断条件和then同在一行时,必须要在判断条件和then命令之间,增加一个分号作为分隔符
1
2
3
4
5
6
7if 条件1 ;then
命令
[elif 条件2 ;then
命令]
[else
命令]
fi
case
语法
1
2
3
4
5
6
7
8
9
10
11
12case 条件 in
模式1)
命令1
;;
[模式2)
命令2
;;
...
模式n)
命令n
;;]
esac“条件”可以是变量、表达式、shell命令等。
“模式”为条件的值,并且一个“模式”可以匹配多种值,不同值之间用竖线(|)联结。模式还可以使用通配符,星号(*)匹配任意字符,问好(?)匹配任意单个字符,[…]匹配某个范围内的字符等。
示例
1
2
3
4
5
6
7
8
9
10
11case $test in
y|Y|yes|Yes)
echo "OK"
;;
n|N|no|No)
echo "NO"
;;
*)
echo "Have a look"
;;
esac
for
语法
1
2
3
4for 变量 [in 列表]
do
命令(通常用到循环变量)
done“列表”为存储一系列值的列表,随着循环的进行,变量从列表的第一个值依次取到最后一个值。如果省略中括号部分,bash则认为是“in $@”,即执行该程序时,通过命令行传给程序的所有参数的列表。
示例
1
2
3
4for os in Linux Windows Unix
do
echo "Operation System is: $os"
done
while和until
- 语法
1
2
3
4while/until 条件
do
命令
done
6. 函数
语法
1
2
3
4[function]函数名()
{
命令
}function可以省略。
调用函数的格式:函数名 [ 参数1 参数2 …… 参数n ]
是否需要参数由函数的定义和功能决定,参数与参数之间用空格分隔。如果在函数内部需要使用传递给函数的参数,一般使用$0、$1、……、$n,以及$#、$*、$@这些特殊变量。$0为执行脚本的函数名,$1表示第一个参数,依次类推,$n为第n个参数;$#为传递给函数的参数个数;$*和$@为传递给函数的所有参数,两者的区别是,$*把所有参数作为一个整体,而$@把所有参数看做拥有多个参数的集合,可以单独访问每个参数。
当向一个完整的shell脚本程序传递参数时,shell程序同样可以通过这些特殊变量来访问传递的参数。这时,这些参数来自终端的命令行,把脚本文件名看做函数名,所有特殊变量的含义和向函数传递时的含义完全一样。
另外,在访问传递的参数时,采用shift命令也是一种常用的方式。shift命令用于将存储在位置变量($1、$2、……、$n)中的变量左移一个位置。
shell程序中的函数也可以有返回值。使用return命令从函数返回值。
7. 示例
结语
本教程到此结束,欢迎指正,互相交流。
版权所有,未经允许,请勿随意转载。