脚本的概念:
如被大家熟知的python脚本、JavaScript脚本和游戏领域经常使用的lua脚本以及今天要说的linux下的shell脚本,它们的共同点就是不需要编译而可以被直接解释并且执行的一种程序。脚本语言也因此被称为动态语言。
在linux下,默认的脚本语言是bash shell脚本。shell译为贝壳,在此处为linux外壳的意思。shell脚本可以理解为一些linux指令的集合。脚本在运维方向以及自动化控制中有着不可或缺的地位,许多项目需要通过脚本运行各种重复的命令来处理相关事务。以下是一个简单的shell脚本例子:
#!/bin/bash
#输出
echo "hello bash shell!"
#!/bin/bash 是程序的开始,必须放在shell脚本的第一行,#!用来告诉系统/bin/bash是用来执行本文件的程序。echo 是shell脚本的输出命令如C语言的printf,以上脚本简单的输出了一句hello bash shell语句。
当在linux下使用vi命令编写并保存好一个脚本后,如hello.sh。可以通过bash hello.sh 运行此脚本。也可以通过chmod命令改变脚本的执行权限。如chmod 775 hello.sh后,可以通过./hello.sh来执行脚本。
shell单行注释:
除第一行#!标识解释器外,其余的#开头的语句表示单行注释。从#开始直到该行的结束为注释部分,如上文的#输出。注释不会在运行结果中打印出来,会被解释器忽略,但是通过注释可以极大的增强脚本的可读性。
多行注释:
#!/bin/bash
:<<BLOCK
echo "note"
echo "lines"
BLOCK
使用:<<BLOCK BLOCK 符号可以对多行命令进行注释。
shell脚本变量与运算符
1、变量定义与赋值操作:
gl@gl:~$ var=hello
gl@gl:~$ echo $var
hello
shell通过$符号来取一个变量中的值,如上,var存放的是hello字符串,通过$符号取出hello,然后经echo命令打印出来。
1)赋值时,字符串直接不能有空格,否则赋值会失败。
gl@gl:~$ var=hello world
No command 'world' found, did you mean:
Command 'tworld' from package 'tworld' (universe)
world: command not found
除非是有双引号"或者单引号'包裹起来。
gl@gl:~$ var="hello world"
gl@gl:~$ echo $var
hello world
2)单引号'和双引号的"区别
双引号:
gl@gl:~$ a="next"
gl@gl:~$ b="$a again"
gl@gl:~$ echo $b
next again
单引号:
gl@gl:~$ a="next"
gl@gl:~$ b='$a again'
gl@gl:~$ echo $b
$a again
可以看到,单引号中的$a保持原样输出。而双引号中的$a会替换成其变量值。
2、算术运算符
gl@gl:~$ a=100
gl@gl:~$ b=200
gl@gl:~$ var=`expr $a + $b`
gl@gl:~$ echo $var
300
通过expr关键字可以实现a变量和b变量的值相加操作。解释一下 ` (键盘感叹号的左边)符号的作用。
即在该符号中的命令会被执行。
常用的算术运算符
运算符 说明 举例
+ 加法 expr $a + $b 结果为 30。
- 减法 expr $a - $b 结果为 10。
* 乘法 expr $a \* $b 结果为 200。
/ 除法 expr $b / $a 结果为 2。
% 取余 expr $b % $a 结果为 0。
= 赋值 a=$b将把变量 b 的值赋给 a。
== 相等 用于比较两个数字,相同则返回 true。[ $a == $b ] 返回 false。
!= 不相等 用于比较两个数字,不相同则返回 true。[ $a != $b ] 返回 true。
3、关系运算符
#!/bin/bash
a=200
b=200
if [ $a -eq $b ]
then
echo true
else
echo false
fi
以上代码表示如果a的值和b的值相等,输出true,否则输出false。
常用的关系运算符
运算符 说明
-eq 检测两个数是否相等,相等返回 true。 [ $a -eq $b ]
-ne 检测两个数是否相等,相等返回 false。
-gt 检测左边的数是否“大于”右边的,如果是,则返回 true。
-lt 检测左边的数是否“小于”右边的,如果是,则返回 true。
-ge 检测左边的数是否“大于等于”右边的,如果是,则返回 true。
-le 检测左边的数是否“小于等于”右边的,如果是,则返回 true。
4、布尔运算符
常用的布尔运算符如下
运算符 说明
! 非运算,表达式为 true 则返回 false,否则返回 true。 [ ! false ]
-o 或运算,有一个表达式为 true 则返回 true。 [ $a -lt 20 -o $b -gt 100 ]
-a 与运算,两个表达式都为 true 才返回 true。 [ $a -lt 20 -a $b -gt 100 ]
5、字符串运算符
常用的字符串运算符如下
运算符 说明
= 检测两个字符串是否相等,相等返回 true。 [ $a = $b ]
!= 检测两个字符串是否相等,不相等返回 true。 [ $a != $b ]
-z 检测字符串长度是否为0,为0返回 true。 [ -z $a ]
-n 检测字符串长度是否为0,不为0返回 true。 [ -n $a ]
6、文件测试运算符
常用的文件测试运算符如下
运算符 说明
-b file 检测文件是否是块设备文件,如果是,则返回 true。 [ -b $file ]
-c file 检测文件是否是字符设备文件,如果是,则返回 true。
-d file 检测文件是否是目录,如果是,则返回 true。
-f file 检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true。
-g file 检测文件是否设置了 SGID 位,如果是,则返回 true。
-k file 检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true。
-p file 检测文件是否是具名管道,如果是,则返回 true。
-u file 检测文件是否设置了 SUID 位,如果是,则返回 true。
-r file 检测文件是否可读,如果是,则返回 true。
-w file 检测文件是否可写,如果是,则返回 true。
-x file 检测文件是否可执行,如果是,则返回 true。
-s file 检测文件是否为空(文件大小是否大于0),不为空返回 true。
-e file 检测文件(包括目录)是否存在,如果是,则返回 true。
shell控制结构
shell脚本的控制结构与C语言的有所不同,但是运用上大同小异。
if-else
#!/bin/bash
var1="hello"
var2="hello"
if [ "$var1" == "$var2" ]
then
echo "ture"
else
echo "false"
fi
需要注意的是[ ]左右必须加空格与变量隔开。fi表示if结构的结束,如C语言中的}括号。
for循环:
#!/bin/bash
vars="a b c d"
for var in $vars
do
echo $var
done
gl@gl:~/shellSet$ bash if.sh
a
b
c
d
while循环:
#!/bin/bash
#输出0-100的和
var=1
sum=0
while [ $var -le 100 ]
do
sum=`expr $var + $sum`
var=`expr $var + 1`
done
echo $sum
gl@gl:~/shellSet$ bash while.sh
5050
for和while以do开始,done表示结束。
case分支:
Shell case语句为多选择语句。可以用case语句匹配一个值与一个模式,
如果匹配成功,执行相匹配的命令。
case语句格式如下:
case $var in
a)
echo "aaa"
;; #表示一个case的结束
b)
echo "bbb"
;;
*) #*表示其他
echo "ccc"
;;
esac #表示结束
case工作方式如上所示。取值后面必须为单词in,每一模式必须以右括号结束。
取值可以为变量或常数。匹配发现取值符合某一模式后,其间所有命令开始执行直至 ;; 。