3.25 第十二章:shell脚本

第十二章:shell脚本

一、什么是shell脚本

把所有操作都记录到一个文档中,然后去调用文档中的命令,这个文档就是shell脚本。Shell脚本能帮助我们很方便地管理服务器,因为我们可以指定一个任务计划,定时去执行某个shell脚本以满足需求。在正式编写shell脚本之前,建议自定义的脚本都放在/usr/local/sbin/目录下:一是可以更好地管理文档;二是以后接管你工作的管理员都知道自定义脚本放在那里,方便维护。

1.shell脚本的创建和执行

编写第一个shell脚本:

[root@zl_cloud ~]# cd /usr/local/sbin/
[root@zl_cloud sbin]# cat first.sh
#! /bin/bash						//表示该文件用的是bash语法
## This is my first shell script			//该脚本是用来干嘛的
## Writen by ZLING 2020-03-25		//作者、时间

Date								//内容
echo "Hello world!"

Shell脚本通常以.sh为后缀名。内容前最好写一个该脚本的相关注释内容,以及作者、创建日期或者版本等, 方便后续回顾查看该脚本。
下面执行一下这个脚本:
①sh命令:

  • -x:查看这个脚本的执行过程。
[root@zl_cloud sbin]# sh first.sh
2020年 03月 25日 星期三 17:37:14 CST
Hello world!
[root@zl_cloud sbin]# 
[root@zl_cloud sbin]# sh -x first.sh
+ date
2020年 03月 25日 星期三 17:38:08 CST
+ echo 'Hello world!'
Hello world!
[root@zl_cloud sbin]# 

②./ 这个格式。(使用该方法运行shell脚本的前提是有脚本本身的执行权限):

[root@zl_cloud sbin]# ./first.sh
-bash: ./first.sh: 权限不够
[root@zl_cloud sbin]# chmod +x first.sh
[root@zl_cloud sbin]# ./first.sh
2020年 03月 25日 星期三 17:39:19 CST
Hello world!
[root@zl_cloud sbin]# 

2.命令date

  • date +%Y:表示以四位数字格式打印年份;
  • date +%y:表示以两位数字格式打印年份;
  • date +%m:表示月份;
  • date +%d:表示日期;
  • date +%H:表示小时;
  • date +%M:表示分钟;
  • date +%S:表示秒;
  • date +%w:表示星期。结果显示0则表示周日。

目前:

[root@zl_cloud sbin]# date +"%Y-%m-%d %H:%M:%S"
2020-03-25 17:48:41
[root@zl_cloud sbin]# 

之前:

[root@zl_cloud sbin]# date -d "-1 day" +%H
17
[root@zl_cloud sbin]# date -d "-1 hour" +%H
16
[root@zl_cloud sbin]# date -d "-1 min" +%H
17
[root@zl_cloud sbin]# 

二、shell脚本中的变量

如果脚本中多次出现某一个命令或路径,而你觉得路径不对想修改一下,就得一个一个修改,或者使用批量修改替换的命令修改。这样就很麻烦,变量就是用来解决这个问题的。
格式:变量名=变量的值
下面编写第一个与变量相关的脚本:

[root@zl_cloud sbin]# vi variable.sh
#! /bin/bash

## In this script we will use variables
## Writen by ZLING 2020-03-25

d=`date +%H:%M:%S`
echo "The script begin at $d"
echo "Now we will sleep 2 seconds"
sleep 2
d1=`date +%H:%M:%S`
echo "The script end at $d1"

例子中的反引号作用是将引号中的字符串当作shell命令执行,返回命令的执行结果。d和d1在脚本中作为变量出现。

[root@zl_cloud sbin]# sh variable.sh 
The script begin at 19:23:38
Now we will sleep 2 seconds
The script end at 19:23:40
[root@zl_cloud sbin]# 

1.数学运算

[root@zl_cloud sbin]# vi sum.sh
#! /bin/bash

## For get the sum of two numbers.
## ZLING 2020-03-25

a=1
b=2
sum=$[$a+$b]
echo "$a+$b=$sum"

数学计算要用[ ]括起来,并且前面要加符号$。

[root@zl_cloud sbin]# sh sum.sh
1+2=3
[root@zl_cloud sbin]# 

2.和用户交互

[root@zl_cloud sbin]# vi read.sh
#! /bin/bash

## Using 'read' in shell script.
## ZLING 2020-03-25

read -p "please inppute a number:" x
read -p "please inppute another number:" y
sum=$[$x+$y]
echo "The sum of the two numbers is $sum"

read命令用于和用户交互,它把用户输入的字符串作为变量值:

[root@zl_cloud sbin]# sh read.sh 
please inppute a number:2          //这里输入了2
please inppute another number:10	//这里输入了10
The sum of the two numbers is 12		//得出的结果
[root@zl_cloud sbin]# 

加上-x选项看看执行过程:

[root@zl_cloud sbin]# sh -x read.sh 
+ read -p 'please inppute a number:' x
please inppute a number:22
+ read -p 'please inppute another number:' y
please inppute another number:13
+ sum=35
+ echo 'The sum of the two numbers is 35'
The sum of the two numbers is 35
[root@zl_cloud sbin]# 

3.shell脚本预设变量

/etc/init.d/iptables restart 命令前面的/etc/init.d/iptables其实就是一个shell脚本。脚本后面为什么可以跟restart字符串呢?这就设置shell脚本的预设变量。实际上,shell脚本在执行时,后面可以跟一个或者多个参数

[root@zl_cloud sbin]# vi option.sh
#! /bin/bash

sum=$[$1+$2]
echo "sum=$sum"
[root@zl_cloud sbin]# sh -x option.sh 1 2
+ sum=3
+ echo sum=3
sum=3
[root@zl_cloud sbin]# 

注意$1和$2就是shell脚本的预设变量。$1和$2的值就是执行时分别输入的1和2,$1就是脚本的第一个参数,$2是脚本的第二个参数,以此类推。预设变量是没有限制的
还有一个$0,代表脚本本身的名字,不妨把脚本修改一下:

[root@zl_cloud sbin]# vi option.sh
sum=$[$1+$2]
#! /bin/bash

echo "$1 $2 $0"
[root@zl_cloud sbin]# sh option.sh 1 2
1 2 option.sh
[root@zl_cloud sbin]# 

三、shell脚本中的逻辑判断

1.不带else

格式:
if (判断语句);then
command
fi

示例脚本如下:

[root@zl_cloud sbin]# vi if1.sh
#! /bin/bash

read -p "Please input your score:" a
if((a<60));then
        echo "You didn't pass the exam."
fi

If1.sh中 出现了((a<60))这样的形式,这是shell脚本特有的格式,只用一个小括号或者不用都会报错,所以要记住这个格式。

[root@zl_cloud sbin]# sh if1.sh 
Please input your score:30
You didn't pass the exam.
[root@zl_cloud sbin]# sh if1.sh 
Please input your score:90

2.带有else

格式:
if (判断语句);then
command
else
command
fi

示例脚本如下:

[root@zl_cloud sbin]# vi if2.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 passed the exam."
fi
[root@zl_cloud sbin]# sh if2.sh 
Please input your score:90
Good! You passed the exam.
[root@zl_cloud sbin]# sh if2.sh 
Please input your score:30
You didn't pass the exam.
[root@zl_cloud sbin]# 

脚本if2.sh和if1.sh唯一的区别是:如果输入大于或等于60的数字会有提示。

3.带有elif

格式:
if (判断语句1);then
command
elif (判断语句2);then
command
else
command
fi

示例脚本如下:

[root@zl_cloud sbin]# vi if3.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 passed the exam."
else
        echo "Very good! Your score is very high!"
fi

这里的&&表示“并且”的意思,当然也可以使用||表示“或者”。

[root@zl_cloud sbin]# sh if3.sh 
Please input your score:60
Good! You passed the exam.
[root@zl_cloud sbin]# sh if3.sh 
Please input your score:90
Very good! Your score is very high!
[root@zl_cloud sbin]# 

判断数值大小除了可以用(())形式外,还可以使用[ ]。但是不能使用大于等于符号了,要使用-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
# a=10; if [$a -ge 10]; then echo ok; fi
ok
# a=10; if [$a -eq 10]; then echo ok; fi
ok
# a=10; if [$a -ne 10]; then echo ok; fi

下面是在if语句中使用&&和||的情况:
# a=10; if [$a -lt 1] || [$a -gt 5]; then echo ok; fi
ok
# a=10; if [$a -gt 1] && [$a -le 10]; then echo ok; fi
ok

4.和文档相关的判断

  • -e:判断文件或目录是否存在;
  • -d:判断是不是目录以及是否存在;
  • -f:判断是不是普通文件以及是否存在;
  • -r:判断是否有读权限;
  • -w:判断是否有写权限;
  • -x:判断是否可执行。

使用if判断时具体格式:
if [-e filename];then
command
fi

示例代码如下:
# if [-d /home/]; then echo ok; fi
ok
# if [-f /home/]; then echo ok; fi
因为/home/是目录而非文件,所以并不会显示ok。其他示例如下:
# if [-f /root/test.txt]; then echo ok; fi
ok
# if [-r /root/test.txt]; then echo ok; fi
ok
# if [-w /root/test.txt]; then echo ok; fi
ok
# if [-x /root/test.txt]; then echo ok; fi
# if [-e /root/test.txt]; then echo ok; fi

5.case逻辑判断

格式:
case 变量 in
value1)
command
;;
Value2)
command
;;
Value3)
command
;;
*)
command
;;
esac

判断输入数值是奇数还是偶数的脚本:

[root@zl_cloud 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 num!”
;;
esac

脚本中$a的值为1或0,执行结果如下:

[root@zl_cloud sbin]# sh case.sh
Input a number:100
“The number is even.”
[root@zl_cloud sbin]# sh case.sh
Input a number:101
“The number is odd.”
[root@zl_cloud sbin]#

case脚本常用于编写系统服务的启动脚本。例如/etc/init.d/network中就用到了。

四、shell脚本中的循环

1.for循环

格式:
for 变量名 in 循环的条件;do
command
` done
示例脚本:

[root@zl_cloud sbin]# vi for.sh
#! /bin/bash

for i in `seq 1 5`;do
        echo $i
done
[root@zl_cloud sbin]# sh for.sh 
1
2
3
4
5
[root@zl_cloud sbin]# 

‘seq 1 5’表示从1到5的一个序列。

[root@zl_cloud sbin]# vi for1.sh
#! /bin/bash

for i in 1 2 3 a b;
        do echo $i;
done
[root@zl_cloud sbin]# sh for1.sh 
1
2
3
a
b
[root@zl_cloud ~]# 

循环的条件还可以引用系统命令的执行结果(如seq 1 5),但必须要用反引号括起来。

[root@zl_cloud sbin]# vi for2.sh
#! /bin/bash

for file in `ls`;
        do echo $file;
done
[root@zl_cloud sbin]# sh for2.sh 
case.sh
first.sh
for1.sh
for2.sh
for.sh
if1.sh
if2.sh
if3.sh
option.sh
read.sh
sum.sh
variable.sh
[root@zl_cloud sbin]# 

2.while循环

有人常用while循环来编写死循环的脚本,用来监控某项服务。
格式:
while 条件 ; do
command
done
示例脚本如下:

[root@zl_cloud sbin]# vi while.sh 
#! /bin/bash

a=5
while (($a >= 1)); do
        echo $a
        a=$[$a-1]
done
[root@zl_cloud sbin]# sh while.sh 
5
4
3
2
1
[root@zl_cloud sbin]#

另外,可==一个冒号代表循环条件,这样可以做到死循环:

[root@zl_cloud sbin]# vi diewhile.sh 
#! /bin/bash

while :; do
        command
        sleep 3
Done
[root@zl_cloud sbin]# sh diewhile.sh   //我试了一下,光标就会一直闪

五、shell脚本中的函数

Shell脚本中的函数就是先把一段代码整理到一个小单元中,并给这个小单元命名,当用到这段代码时直接调用这个小单元的名字即可。有时候脚本中的某段代码总是重复使用,如果写成函数,每次用到时直接用函数名代替即可。
示例脚本如下:

[root@zl_cloud sbin]# vi func.sh
#! /bin/bash

function sum()
{
        sum=$[$1+$2]
        echo $sum
}

sum $1 $2
[root@zl_cloud sbin]# sh func.sh 1 2
3
[root@zl_cloud sbin]# 

func.sh 中的sum()为自定义函数。在shell脚本中函数格式如下:
function 函数名()
{
command1
command2
}
需要注意的是,在shell脚本中,函数一定要写在最前面。因为函数是要被调用的,如果还没有出现就被调用,肯定会出错。

六、shell脚本中的终端和继续

1.break

break用在循环中,不管是for还是while都可以。在脚本中使用它,表示退出该层循环。之所以时层,是因为我们有时候用的嵌套循环,大循环里面还有小循环,而break只是退出那一层循环,他的上层循环不受影响。

[root@zl_cloud 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 aaaa
[root@zl_cloud sbin]# sh break.sh 
1
1
2
2
3
aaaa
[root@zl_cloud sbin]# 

2.continue

continue也是用在循环中的,和break不同的是,当在shell脚本中遇到continue时,结束的不是整个循环,而是本次循环。

[root@zl_cloud 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
[root@zl_cloud sbin]# sh continue.sh 
1
1
2
2
3
4
4
5
5
5
[root@zl_cloud sbin]# 

3.exit

与前两个功能类似,但是它的作用范围更大,直接退出整个shell脚本。

[root@zl_cloud 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 aaaa
[root@zl_cloud sbin]# sh exit.sh
1
1
2
2
3
[root@zl_cloud sbin]# 

猜你喜欢

转载自blog.csdn.net/zhang_ZERO/article/details/105123071
今日推荐