Shell脚本
一、shell脚本的创建和执行
1、编写脚本
# cd /usr/local/sbin/ # vi first.sh //内容如下所示 #! /bin/bash ## This is my first shell script. //说明和日期都是注释的内容 ## Writen by tcq 2021-04-19. //最好写上,方便记忆 date echo "Hello world"
2、执行脚本
[root@shell sbin]# sh first.sh //执行结果如下:
2021年 04月 19日 星期一 21:26:38 CST
Hello world
还有一种执行方式,示例如下:
[root@shell sbin]# chmod +x first.sh //新建的脚本需要 增加执行权限 [root@shell sbin]# ./first.sh 2021年 04月 19日 星期一 21:28:16 CST Hello world
加上-x可以查看脚本的执行过程,示例如下:
[root@shell sbin]# sh -x first.sh + date 2021年 04月 19日 星期一 21:30:41 CST + echo 'Hello world' Hello world
3、命令date
date的几个基本用法如下所示:
l date +%Y: 表示以四位数字格式打印年份。
l date +%y: 表示以两位数字格式打印年份。
l date +%m: 表示月份。
l date +%d: 表示日期
l date +%H: 表示小时。
l date +%M: 表示分钟。
l date +%S: 表示秒。
l date +%w:表示星期,结果显示0则表示周日。
示例:
# date +"%Y-%m-%d %H:%M:%S"
2021-04-19 21:40:16
# date -d "-1 day" +%d //显示前一天的日期
18
# date -d "-1 hour" +%H //显示前一小时
20
# date -d "-1 min" +%M //显示前一分钟
43
二、shell脚本中的变量
1、编写一个与变量相关的脚本
# [root@shell sbin]# vi variadle.sh #! /bin/bash ## In this script we will write many variable ## Writen by tcq 2021-04-19 d=`date +%H:%M:%S` echo "The script begin at $d." echo "Now we'll sleep 2 seconds." sleep 2 d1=`date +%H:%M:%S` echo "The script end at $d1."
执行脚本:
# ./variadle.sh The script begin at 22:00:26. Now we'll sleep 2 seconds. The script end at 22:00:28.
2、数学运算
示例如下:
[root@shell sbin]# vi sum.sh #! /bin/bash ## This is about math of shell. ## Writen by tcq 2021-04-19 a=1 b=2 sum=$[$a+$b] //数学运算要用[ ]括起来,前面要加$ echo "$a+$b=$sum" # sh sum.sh 1+2=3
3、和用户交互
[root@shell sbin]# vi read.sh #! /bin/bash ## Using 'read' in shell script. ## tcq 2021-04-19 read -p "Please input a number:" x read -p "Please input another number:" y sum=$[$x+$y] echo "The sum of the two numbers is: $sum" 执行脚本: [root@shell sbin]# sh read.sh Please input a number:100 Please input another number:2 The sum of the two numbers is: 102
4、shell脚本预设变量
[root@shell sbin]# vi option.sh #! /bin/bash sum=$[$1+$2] echo "sum=$sum" [root@shell sbin]# sh option.sh 4 5 sum=9
上面这4和5就是脚本的预设变量,预设变量时没有限制的,$0代表脚本本身,示例如下:
[root@shell sbin]# vi option.sh //修改脚本 #! /bin/bash echo "$1 $2 $0" [root@shell sbin]# sh option.sh 1 2 1 2 option.sh //这里$0=option.sh
三、shell脚本中的逻辑判断
1、不带else
具体格式如下:
if 判断语句; then
command
fi
示例脚本如下:
[root@shell sbin]# vi option.sh //修改脚本 #! /bin/bash echo "$1 $2 $0" [root@shell sbin]# sh option.sh 1 2 1 2 option.sh //这里$0=option.sh
2、带有else
具体格式如下:
if 判断语句; then
command
else
command
fi
示例脚本如下:
[root@shell sbin]# vi if1.sh #! /bin/bash read -p "Please input your score:" a if ((a<60)); then echo "You didn't pass the exam." else echo "Good! You pass the exam." fi 脚本执行结果如下: [root@shell sbin]# sh if1.sh Please input your score:0 You didn't pass the exam. [root@shell sbin]# sh if1.sh Please input your score:90 Good! You pass the exam.
3、带有elif
具体格式如下:
If 判断语句1; then
command
elif 判断语句2; then
command
else
command
fi
示例脚本如下:
[root@shell sbin]# vi if1.sh #! /bin/bash read -p "Please input your score:" a if ((a<60)); then echo "You didn't pass the exam." elif ((a>=60)) && ((a<85)); then echo "Good! You pass the exam." else echo "Very good! Your score is very high!" fi
执行结果如下:
判断数值除了用(())的形式外,还可以使用[],但是不能使用<,>,=这样的符号,要使用-lt(小于)、-gt(大于)、-le(小于或等于)、-ge(大于或等于)、-eq(等于)、-ne(不等于)。示例如下:
# a=10; if [ $a -lt 5 ]; then echo ok; fi # a=10; if [ $a -gt 5 ]; then echo ok; fi ok &&和||的使用,使用&&时,只有两边都符号才会输出ok,而使用||时,只要有一边符合,就会输出ok,示例如下: # a=10; if [ $a -gt 5 ] && [ $a -lt 14 ]; then echo ok; fi ok # a=10; if [ $a -gt 5 ] || [ $a -lt 5 ]; then echo ok; fi ok
4、和文档相关的判断
(1)If常用的选项有以下几个:
² -e:判断文件或目录是否存在。
² -d:判断是不是目录以及是否存在。
² -f:判断是不是普通文件以及是否存在。
² -r:判断是否有读权限。
² -w:判断是否有写权限。
² -x:判断是否有执行权限。
² -z:字符串空为真。
² -s:文件大小不为0为真。
(2)使用if判断时的具体格式如下:
if [ -e filename ]; then
command
fi
示例代码如下:
# if [ -d /home/ ]; then echo ok; fi
ok
5、case判断
具体格式如下:
case 变量 in value1) command ;; value2) command ;; *) command ;; esac
编写一个判断是奇数还是偶数的脚本:
[root@shell sbin]# vi case.sh #! /bin/bash read -p "Input a number:" n a=$[$n%2] case $a in 1) echo "The number is odd." ;; 0) echo "The number is even." ;; *) echo "It's not a number!" ;; esac
执行结果如下:
四、Shell脚本中的循环
1、for循环
写一个简单的for循环脚本,实例如下:
[root@shell sbin]# vi for.sh #! /bin/bash for i in `seq 1 5`; do //seq 1 5 表示1到5的一个序列 echo $i Done
执行脚本:
[root@shell sbin]# sh for.sh
1
2
3
4
5
这个脚本就是for循环的基本结构,具体格式如下所示:
for 变量名 in 循环的条件; do
command
done
循环的条件可以是一组字符串或者数字(用一个或者多个空格隔开),也可以是一条命令的执行结果,示例如下:
# for i in 1 2 3 a b; do echo $i; done
1
2
3
a
b
也可以引用系统命令的执行结果(如seq 1 5),但是必须用反引号括起来,示例如下:
# for file in `ls`; do echo $file; done case.sh first.sh for.sh if1.sh option.sh read.sh sum.sh variadle.sh
2、while循环
基本格式如下:
while 条件; do
command
done
示例脚本如下:
[root@shell sbin]# vi while.sh #! /bin/bash a=5 while [ $a -ge 1 ]; do echo $a a=$[$a-1] done
执行结果如下:
[root@shell sbin]# sh while.sh
5
4
3
2
1
如果用冒号代替循环条件,就可以做到死循环,示例如下:
[root@shell sbin]# cat while.sh #! /bin/bash while :; do echo "hahahahahahahaha" done
执行结果如下:
五、shell脚本中的函数
1、写一个带有函数功能的脚本
[root@shell sbin]# vi func.sh #! /bin/bash function sum() { sum=$[$1+$2] echo $sum } sum $1 $2
执行结果如下:
[root@shell sbin]# sh func.sh 1 2
3
func.sh中的sum()为自定义的函数,函数一定要写在最前面,不能出现在中间或者最后,因为函数是被调用的,所有得先出现,才能被调用。
六、shell脚本中的中段和继续
1、break
在使用break时都是打破循环的意思,break只打破它所在的那一层循环,它的上层循环不受影响,示例如下:
[root@shell sbin]# vi break.sh #! /bin/bash for i in `seq 1 5` do echo $i if [ $i == 3 ] then break fi echo $i done echo aaaaa
执行结果如下:
2、continue
continue和break不同的是当shell中遇到continue时,结束的不是整个循环,而是本次循环,示例如下:
[root@shell sbin]# vi continue.sh #! /bin/bash for i in `seq 1 5` do echo $i if [ $i == 3 ] then continue fi echo $i done echo $i
如上脚本所示,当i=3时,contunue出现,结束本次循环,continue后面的语句不再执行,继续下一次循环,执行结果如下:
[root@shell sbin]# sh continue.sh
1
1
2
2
3
4
4
5
5
3、exit
和break、continue相比,exit的作用范围更大,直接退出整个脚本,示例如下:
[root@shell sbin]# vi exit.sh #! /bin/bash for i in `seq 1 5` do echo $i if [ $i == 3 ] then exit fi echo $i done echo aaaaaa
执行结果如下:
[root@shell sbin]# sh exit.sh
1
1
2
2
3
由上可以看出,当i=3时,直接退出脚本,后面没有执行。
七、shell中的数组
1、定义数组
[root@shell ~]# a=(1 2 3 4 5) //定义数组 [root@shell ~]# echo ${a[@]} 1 2 3 4 5 [root@shell ~]# echo ${#a[@]} //获取数组的元素个数 5 [root@shell ~]# echo ${a[2]} //读取第三个元素,数组从0开始 3 [root@shell ~]# echo ${a[*]} //等同于 ${a[@]} 显示整个数组 1 2 3 4 5
2、数组赋值
[root@shell ~]# a[1]=100 [root@shell ~]# echo ${a[@]} //@和*作用相同,都是打印所有元素 1 100 3 4 5 [root@shell ~]# a[5]=2 //如果下标不存在则会自动添加一个元素 [root@shell ~]# echo ${a[@]} 1 100 3 4 5 2 [root@shell ~]# unset a[5] //删除数组 [root@shell ~]# echo ${a[@]} 1 100 3 4 5 //a[5]已经被删除 [root@shell ~]# unset a [root@shell ~]# echo ${a[@]} //不显示结果,数组已经被删除
3、数组分片
[root@shell ~]# a=(`seq 1 5`) [root@shell ~]# echo ${a[@]:0:3} //从第一个元素开始,截取3个 1 2 3 [root@shell ~]# echo ${a[@]:2:3} //从第三个元素开始,截取3个 3 4 5 [root@shell ~]# echo ${a[@]:0-3:2} //从倒数第3个元素开始,截取2个 3 4
4、数组替换
[root@shell ~]# echo ${a[@]/3/100}
1 2 100 4 5
a=(${a[@]/3/100})