Linux脚本

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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,判断用户输入文件路径,显示其文件类型(普通,目录,链接,其它文件类型)

    技术分享

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

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

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

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

    技术分享


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

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

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

二、case语句

case 变量引用 in

    pat1)

        分支1

        ;;

    pat2)

        分支2

        ;;

    *)

默认分支

        ;;

    esac

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

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

    技术分享


    脚本思路(1read -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) 变量引用; [email protected], $*

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

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

    技术分享


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

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

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

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

2、打印九九乘法表

    技术分享


    次数用到for嵌套for

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

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

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

    执行结果如下:

    技术分享


for语句的第二种用法:

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

command ;

done

用流程图表示如下:

    技术分享

while语句和untile语句

    while语句:

    while CONDITION do

        循环体

    done

 

    untile语句:

until CONDIOION do

        循环体

    done

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

    while的特殊用法:

    while read line ;do

        循环体

    done < 文件路径

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

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

    技术分享

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

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

    技术分享   

    脚本思路(1)先定义isum的基础值

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

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


2、禁止某个用户登录

    技术分享


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

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

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

    while还能创建无限循环

    while true ;do

        循环体

    done

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


五、continue用法

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

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

    技术分享


    脚本思路(1)先定义isum的基础值

            (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,依次创建四个账户。

    技术分享


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

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

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


八、select语法

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

例子:编写一个菜单

    技术分享

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

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

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


九、trap的用法

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

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

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

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

例子:

    技术分享

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

十、函数

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

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


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

Shell程序在子Shell中运行

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


定义一个函数:

    function () {

        ...函数体...

    }

删除一个函数:unset function

查看一个函数:declare -i function

脚本里面的返回值:return

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

生成环境函数:export -f function

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

技术分享

例子:

    编写服务脚本/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 文件路径  判断该文件是否存在

执行结果如下:

    技术分享

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

其中的代码如下:

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 "\<start\>|\<stop\>|\<restart\>|\<status\>" &> /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

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

        例如: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:要取出的元素个数

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

技术分享

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

技术分享

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

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

以上是关于Linux脚本的主要内容,如果未能解决你的问题,请参考以下文章

如何在windows下使用linux的shell脚本

linux 中如何执行脚本?

linux脚本运行后把脚本删了会怎么办

linux 中如何执行脚本?

在linux中怎么运行脚本函数

如何查看 linux开机启动脚本