Linux基础知识之shell脚本

第12章 shell脚本

2020/03/27
第9课

12.1 什么是shell脚本

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

12.1.1 shell脚本的创建和执行

编写第一个shell脚本:

[root@xxj-could sbin]# cat first.sh
#! /bin/bash    //表示该文件用的是bash语法,#表示注释

#This is my first shell script.
#Writen by xxj 2020-03-27

date
echo "Hello world!"

[root@xxj-could sbin]#

Shell脚本通常是以.sh为后缀的文件。在shell脚本中最好写一些该脚本的相关注释内容,以及作者、创建日期或者版本等。
执行一下脚本:

[root@xxj-could sbin]# sh first.sh    //执行脚本
Mon Mar 30 16:26:35 EDT 2020
Hello world!
[root@xxj-could sbin]# chmod +x first.sh    //脚本本身有执行权限,需要给脚本加一个+x权限
[root@xxj-could sbin]# ./first.sh    //执行脚本的另一种方法
Mon Mar 30 16:27:29 EDT 2020
Hello world!
[root@xxj-could sbin]# sh -x first.sh    //加-x选项可以查看这个脚本的执行过程
+ date
Mon Mar 30 16:34:05 EDT 2020
+ echo 'Hello world!'
Hello world!
[root@xxj-could sbin]# 
12.1.2 命令date
  • date +%Y:表示以四位数字格式打印年份。
  • date +%y:表示以两位数字格式打印年份。
  • date +%m:表示月份。
  • date +%d:表示日期。
  • date +%H:表示小时。
  • date +%M:表示分钟。
  • date +%S:表示秒。
  • date +%w:表示星期。结果显示0则表示周日。

date命令用法:

[root@xxj-could sbin]# date +"%Y-%m-%d %H:%M:%S"
2020-03-27 16:43:06
[root@xxj-could sbin]# date -d "-1 day" +%d
26
[root@xxj-could sbin]# date -d "-1 hour" +%H
15
[root@xxj-could sbin]# date -d "-1 min" +%H
16
[root@xxj-could sbin]# 

12.2 shell脚本中的变量

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

[root@xxj-could sbin]# vi variable.sh
#! /bin/bash

## In this script we will use variables
## Writen by xxj 2020-03-27

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"
[root@xxj-could sbin]# sh variable.sh 
The script begin at 17:03:43
Now we will sleep 2 seconds
The script end at 17:03:45
[root@xxj-could sbin]# 

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

12.2.1 数学运算

示例脚本:

[root@xxj-could sbin]# cat sum.sh
#! /bin/bash

## For get the sum of two numbers.
## xxj 2020-03-27

a=1
b=2
sum=$[$a+$b]
echo "$a+$b=$sum"
[root@xxj-could sbin]# sh sum.sh 
1+2=3
[root@xxj-could sbin]# 

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

12.2.2 和用户交互

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

[root@xxj-could sbin]# cat read.sh
#! /bin/bash

## Using 'read' in shell script.
## xxj 2020-03-27

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"
[root@xxj-could sbin]# sh read.sh    
please inppute a number:2
please inppute another number:10
The sum of the two numbers is 12
[root@xxj-could sbin]# sh -x read.sh    //加-x选项看看执行过程
+ 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@xxj-could sbin]# 
12.2.3 shell脚本预设变量

/etc/init.d/iptables restart 命令前面的/etc/init.d/iptables其实就是一个shell脚本。脚本后面跟的restart字符串就涉及到shell脚本的预设变量。实际上,shell脚本在执行时,后面可以跟一个或者多个参数。
示例脚本:

[root@xxj-could sbin]# cat option.sh
#! /bin/bash

sum=$[$1+$2]
echo "sum=$sum"
[root@xxj-could sbin]# sh -x option.sh 1 2
+ sum=3
+ echo sum=3
sum=3
[root@xxj-could sbin]# cat option.sh
#! /bin/bash

echo "$1 $2 $0"
[root@xxj-could sbin]# sh option.sh 1 2
1 2 option.sh
[root@xxj-could sbin]# 

其中$1和$2就是shell脚本的预设变量。$1和$2的值就是在执行时分别输入的1和2,$1就是脚本的第一个参数,$2是脚本的第二个参数,以此类推。shell脚本的预设变量是没有限制的。还有一个$0,代表脚本本身的名字。

12.3 shell脚本中的逻辑判断

12.3.1 不带else

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

示例脚本:

[root@xxj-could sbin]# cat if1.sh
#! /bin/bash

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

[root@xxj-could sbin]# sh if1.sh 
Please input your score:90
[root@xxj-could sbin]# sh if1.sh 
Please input your score:33
You didn't pass the exam.
[root@xxj-could sbin]# 

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

12.3.2 带有else

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

示例脚本:

[root@xxj-could sbin]# cat 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@xxj-could sbin]# sh if2.sh 
Please input your score:80
Good! You passed the exam.
[root@xxj-could sbin]# sh if2.sh 
Please input your score:25
You didn't pass the exam.
[root@xxj-could sbin]# 

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

12.3.3 带有elif

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

示例脚本:

[root@xxj-could sbin]# cat 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@xxj-could sbin]# sh if3.sh 
Please input your score:90
Very good! Your score is very high!
[root@xxj-could sbin]# sh if3.sh 
Please input your score:60   
Good! You passed the exam.
[root@xxj-could 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
12.3.4 和文档相关的判断

格式:
if [-e filename];then
command
fi

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

示例代码:

# 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
12.3.5 case逻辑判断

格式:(不限value的个数,*代表其他值)
case 变量 in
value1)
command
;;
Value2)
command
;;
Value3)
command
;;
*)
command
;;
esac

示例脚本,判断输入数值是奇数还是偶数:

[root@xxj-could sbin]# cat 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
[root@xxj-could sbin]# sh case.sh 
Input a number:100
The number is even.
[root@xxj-could sbin]# sh case.sh 
Input a number:101
The number is odd.
[root@xxj-could sbin]# 

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

12.4 shell脚本中的循环

12.4.1 for循环

格式:
for 变量名 in 循环的条件;do
command
done

示例脚本:

[root@xxj-could sbin]# cat for.sh
#! /bin/bash

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

“循环的条件”可以是一组字符串或者数字(用一个或者多个空格隔开),也可以是一条命令的执行结果

[root@xxj-could sbin]# for i in 1 2 3 a b; do echo $i; done   //以一条命令的形式
1
2
3
a
b
[root@xxj-could sbin]# 

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

[root@xxj-could sbin]# for file in `ls`; do echo $file; done
case.sh
first.sh
for.sh
if1.sh
if2.sh
if3.sh
option.sh
read.sh
sum.sh
variable.sh
[root@xxj-could sbin]# 
12.4.2 while循环

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

示例脚本:

[root@xxj-could sbin]# cat while.sh
#! /bin/bash

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

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

[root@xxj-could sbin]# cat while.sh
#! /bin/bash

a=5
while :; do
command
sleep 3
done
[root@xxj-could sbin]# sh while.sh     //没有结果

12.5 shell脚本中的函数

Shell脚本中的函数就是先把一段代码整理到一个小单元中,并给这个小单元命名,当用到这段代码时直接调用这个小单元的名字即可。这样遇到总是重复使用的代码就会节省时间和空间。

格式:
function 函数名()
{
command1
command2
}

需要注意的是,在shell脚本中,函数一定要写在最前面。因为函数是要被调用的,如果还没有出现就被调用,肯定会出错。

示例脚本:

[root@xxj-could sbin]# cat func.sh
#! /bin/bash

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

sum $1 $2
[root@xxj-could sbin]# sh func.sh 1 2
3
[root@xxj-could sbin]# 

12.6 shell脚本中的中断和继续

12.6.1 break

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

[root@xxj-could sbin]# cat break.sh
#! /bin/bash
for i in `seq 1 5`
do
    echo $i
    if [ $i == 3 ]
    then
            break
    fi
    echo $i
done
echo aaaaaa
[root@xxj-could sbin]# sh break.sh 
1
1
2
2
3
aaaaaa
[root@xxj-could sbin]# 

上例脚本中本意把1~5数值赋予i,当i等于3时,会跳出循环,后面的4和5都不会再执行了。

12.6.2 continue

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

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

当i等于3时,出现continue,所以结束本次循环,continue后面的语句不再循环,继续下一次循环。

12.6.3 exit

它的作用范围更大,直接退出整个shell脚本。
示例脚本:

[root@xxj-could sbin]# cat exit.sh
#! /bin/bash

for i in `seq 1 5`
do
    echo $i
    if [ $i == 3 ]
    then
            exit
    fi
    echo $i
done
echo aaaaa
[root@xxj-could sbin]# sh exit.sh 
1
1
2
2
3
[root@xxj-could sbin]# 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值