LINUX脚本报错捕捉,Linux脚本

这周是最烧脑的一周,每天都沉迷在如何编写脚本中,我相信脚本这块让大家都很头疼,包括以后的工作肯定也离不开脚本。那么我们接下来针对脚本这块给大家做个详细的分析。

一、if语句

单分支:if判断条件;then

条件为真的分支代码

fi

双分支:if判断条件; then

条件为真的分支代码

else

条件为假的分支代码

fi

多分支:if判断条件1; then

条件为真的分支代码

elif判断条件2; then

条件为真的分支代码

elif判断条件3; then

条件为真的分支代码

else

以上条件都为假的分支代码

fi

if语句的基本格式就是以上的形式,那么下面的两个例子让你对if语句加深印象

1、编写脚本/root/bin/filetype.sh,判断用户输入文件路径,显示其文件类型(普通,目录,链接,其它文件类型)

99815785a138bf6638da67166621da7e.png

脚本思路(1)用read -p交互式让用户输入文件路径

(2)判断该文件是否存在,以防用户输入的文件是不存在的

(3)然后用-h,-d,-f分别判断文件是否为软连接,目录还是普通文件。

2、编写脚本/root/bin/checkint.sh,判断用户输入的参数是否为正整数

bf6259c529ef82f36a576a60497d4f3b.png

脚本思路(1)用read -p交互式提示用户输入数字

(2)判断用户是否输入的是正数

(3)判断用户输入的正数是否是小数,如何判断是否是小数,只用看是否带“.”就行

二、case语句

case变量引用in

pat1)

分支1

;;

pat2)

分支2

;;

*)

默认分支

;;

esac

case语句适用于判断输入的关键字,那么下来以例子的形式加深印象

1、判断用户输入的是yes或者是no。

af49f0e5382c51ed0b380e4a8f3ae20d.png

脚本思路(1)read -p交互式提示用户输入字符串

(2)根据用户可能输入yes的各种形式去判断

(3)根据用户可能输入no的各种形式去判断

(4)除了yes或者no就给用户提示不知道输入的是什么意思

三、for语句

for变量名in列表;do

循环体

done

列表的生成方式:

(1)直接给出列表

(2)整数列表:(a) {start..end}

(b) $(seq [start [step]] end)

(3)返回列表的命令$(COMMAND)

(4)使用glob,如:*.sh

(5)变量引用;$@, $*

for循环只要针对数字,下面还用事例加深for印象

1、编写脚本,提示输入正整数n的值,计算1+2+…+n的总和

a6548a8c6def3b027496a78440a08f77.png

脚本思路(1)read -p交互式提示用户输入正整数n

(2)判断用户输入的是否是正整数,如果不是正整数提示用户后并退出

(3)如果输入的是正整数,用for循环,列表是从1到n,循环体就是let sum+=$i

(4)直到循环n次后结束,输出sum值就行

2、打印九九乘法表

5fffebc88bb8ce3f298e06f2d6ec4ebd.png

次数用到for嵌套for

脚本思路(1)九九乘法表需要循环九次

(2)外面每循环一次,里面就需要从1×到$sum

(3)里面循环结束都需要换行,所以要在内部循环结束后加echo

执行结果如下:

f7f7b26bd733c35aea6bce6a73237ad6.png

for语句的第二种用法:

for ((exp1;exp2;exp3)) ;do

command ;

done

用流程图表示如下:

35505ea509cfa2e85eeb3d48bb5bc24a.png

四、while语句和untile语句

while语句:

while CONDITION;do

循环体

done

untile语句:

until CONDIOION;do

循环体

done

为什么要把while和untile语句放一块呢,因为这两个的用法刚好相反,while中当CONDITION为真的时候会一直循环下去,直到CONDITION为假就退出脚本。而untile中当CONDITION为假的时候会一直循环下去,直到CONDITION为真就退出脚本。

while的特殊用法:

while read line ;do

循环体

done

依次读取文件里面的每一行,且将行赋值给变量line

例如:截取出来UID大于100且小于200的值

f720804528b5aeddf0236945ee43b055.png

下面我们用例子给大家展示一下while的用法以及untile的用法

1、编写脚本,求100以内所有正奇数之和

6729821bc1332da427acd4be59bf2fd6.png

脚本思路(1)先定义i和sum的基础值

(2)然后用while循环,条件就为i小于100就退出

(3)循环体为let sum+=$i和i每次加2

2、禁止某个用户登录

bc41b0108918b9d7456188e493807d88.png

脚本思路(1)用who命令去查看,然后把该用户截取出来

(2)每0.5秒检查一次,看该用户是否登录

(3)如果条件为真,那么就推出循环,就把该用户kill掉

while还能创建无限循环

while true ;do

循环体

done

此处的CONDITION只要换成true或者:就行

五、continue用法

continue只是结束本次循环进入下次循环,所以continue的位置一定要考虑清楚

例如:计算前100正奇数数的和,但是51不相加。

bcd8628daee23488bea39540dcd36ed2.png

脚本思路(1)先定义i,sum的基础值

(2)循环判断i是否小于等于100

(3)判断i是否等于51,如果等于51就不去执行后面的命令,跳过本次循环

(4)如果不是51,判断余数是否等于1,等于1就去执行let sum+=I

(5)循环结束后,输出sum的值就行

六、break的用法

脚本中遇到break就直接结束循环体,相对于continue是直接退出循环体,而不是退出本次循环

对于上面例子,如果把continue换成break就是相当与遇到51后就直接退出循环体。

七、shift用法

shift适用于不确定的位置参数

例子:输入参数a b c d,依次创建四个账户。

0674b8708d0a5fda7464cf3ff5aa1743.png

脚本思路(1)先判断该用户是否输入参数,如果没有输入参数就直接退出,并提醒用户输入参数

(2)判断第一个参数是否存在,如果存在就创建用户shift将第一个变量删除,第二个变量成为第一个变量

(3)直到最后一个参数变为第一个参数结束时,退出循环。

八、select语法

select非常适用于编辑菜单脚本

例子:编写一个菜单

96634a956deaeb3c462932505e65de1c.png

脚本思路(1)用select生成菜单编号和菜单名称

(2)用case语法检测用户输入的关键字

(3)这里的PS3是更改多行提示符

九、trap的用法

trap适用于脚本中信号捕捉,可以屏蔽一些信号。

trap ‘‘信号忽略信号的操作

trap ‘-‘信号恢复原信号的操作

trap -p列出自定义信号操作

例子:

524907a82b9e90f998585d4d97bd6f01.png

这个脚本只是针对trap的一些用法,大家可以去试试。

十、函数

函数function是由若干条shell命令组成的语句块,实现代码重用和模块化编程

它与shell程序形式上是相似的,不同的是它不是一个单独的进程,不能独立运行,而是shell程序的一部分

函数和shell程序比较相似,区别在于:

Shell程序在子Shell中运行

而Shell函数在当前Shell中运行。因此在当前Shell中,函数可以对shell中变量进行修改

定义一个函数:

function () {

...函数体...

}

删除一个函数:unset function

查看一个函数:declare -i function

脚本里面的返回值:return

return和exit的区别:return专应用于函数,相当于exit退出脚本,但是函数是当前Shell ,如果要用exit就直接退出了,所以需要用return。函数中尽量不写exit

生成环境函数:export -f function

我们的机器开机的时候在启动一些服务时候后面总是显示[ok]或者[FAILED]。这是通过调用/etc/init.d/functions/里面的函数实现的:

7e68c98166265fc60c2743010f0c5e3b.png

例子:

编写服务脚本/root/bin/testsrv.sh,完成如下要求

(1)脚本可接受参数:start, stop, restart, status

(2)如果参数非此四者之一,提示使用格式后报错退出

(3)如是start:则创建/var/lock/subsys/SCRIPT_NAME,并显示“启动成功”

考虑:如果事先已经启动过一次,该如何处理?

(4)如是stop:则删除/var/lock/subsys/SCRIPT_NAME,并显示“停止完成”

考虑:如果事先已然停止过了,该如何处理?

(5)如是restart,则先stop,再start

考虑:如果本来没有start,如何处理?

(6)如是status,则如果/var/lock/subsys/SCRIPT_NAME文件存在,则显示“SCRIPT_NAMEis running...”

如果/var/lock/subsys/SCRIPT_NAME文件不存在,则显示“SCRIPT_NAME is stopped...”

其中:SCRIPT_NAME为当前脚本名(testsrv.sh)-e文件路径判断该文件是否存在

执行结果如下:

2fc4b409e8f304085966c7aad6feaf39.png

有兴趣的可以看下是如何实现的

其中的代码如下:

f_start() {

ls /var/lock/subsys/testsrv.sh &> /dev/null

if [ $? -eq 0 ];then

action "该服务已经启动" true

else

touch /var/lock/subsys/testsrv.sh

action "启动成功" true

fi

}

f_stop() {

ls /var/lock/subsys/testsrv.sh &> /dev/null

if [ $? -eq 0 ];then

rm -f /var/lock/subsys/testsrv.sh

action "停止完成" false

else

action "该服务已经停止" false

fi

}

f_restart() {

f_stop &> /dev/null

f_start &> /dev/null

action "该服务已经重新启动" true

}

f_status() {

ls /var/lock/subsys/testsrv.sh &> /dev/null

if [ $? -eq 0 ] ;then

action "testsrv.sh is running..." true

else

action "testsrv.sh is stopped..." false

fi

}

echo $1 |egrep -o "\|\|\|\" &> /dev/null

[ $? -ne 0 ] && { echo "请准确输入!!"; exit 10; }

. /etc/init.d/functions

if [ "$1" == start ];then

f_start

elif [ "$1" == stop ];then

f_stop

elif [ "$1" == restart ];then

f_restart

else

f_status

fi

整体思路就是,定义四个函数f_start,f_stop,f_restart,f_status。然后在脚本里面掉调用这四个函数就行。

十一、数组

数组:(有稀疏格式,有连续格式)

创建数组时候先声明变量:(在脚本里面也是先声明数组)

declare -a数组名称声明普通数组

declare -A数组名称声明关联数组

关联数组与普通数组不能相互转换

创建数组:

一次只赋值一个的时候:数组名称[number]=名称weekdays[0]=Sunday

直接添加变量到数组中是最后一个:数组名称[${#数组名称(*)}]=val4

一次性赋值全部元素的时候,如果有特殊符号的时候需要加””:数组名称=(“val1”“val2”“val3”....)

例如:title=([0]=wang [1]=xiaoming [2]=”xiaohong”)

只赋值特定元素的时候:数组名称=([0]=“val1”[2]=“val2”....)

例如:title=([0]=wang [2]=xiaoming [4]=”xiaohong”)

交互式数组赋值:read -a数组名称

显示数组里面的变量:

显示单个数组里面的变量:echo ${数组名称[number]}

显示数组里面全部的变量:echo ${数组名称[*]}或者echo ${数组名称[@]}

显示数组里面全部变量的个数:echo ${#数组名称[*]}

删除数组里面的变量

删除数组中的单个变量:unset数组名称[number]

删除数组中的最后一个变量:unset数组名称[$[${#数组名称[*]}-1]]

删除整个数组:unset数组名称

declare -a查看数组

数组切片:

echo ${数组名称[*]:number1:number2}

number1:要跳过的元素个数

number2:要取出的元素个数

例子:编写脚本实现生成是个数字,比较出最大的和最小的数字

f382ac02de71a2821699dc1229b6dbc0.png

例子:编写一个脚本,把/var/log/*.log放入数组中,并计算出偶数下表的总行数

42a7338e13a170be3794f8f8fd730aa3.png

其实我们平时写脚本的时候,可以先在本上把思路写好,然后按照本上的思路先都敲出来,然后再慢慢排错,我感觉这样写脚本会比边想边敲代码效率会更高。大家可以去尝试一下!

但是每个人有每个人的学习方法,在此仅仅是建议。希望能够帮到大家!!

原文:http://13296637.blog.51cto.com/13286637/1965883

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值