我的朗科运维第八课

shell编程之执行结构

站在用户的角度思考问题,与客户深入沟通,找到北辰网站设计与北辰网站推广的解决方案,凭借多年的经验,让设计与互联网技术结合,创造个性化、用户体验好的作品,建站类型包括:做网站、成都网站制作、企业官网、英文网站、手机端网站、网站推广、域名申请雅安服务器托管、企业邮箱。业务覆盖北辰地区。

case分支选择结构:

    case 词 in [模式 [| 模式] ...) 命令 ;; ] ... esac

    case 变量引用 in    

        模式1)

            分支1

            ;;

        模式2)

            分支2

            ;;

        ...

        *)

            默认分支

            ;;

    esac

模式(PATTERN):

    1.普通的文本字符

    2.globbing风格的通配符

        *:任意长度任意字符

        ?:任意的单个字符

        []:范围内的任意单个字符

        [^]:范围外的任意单个字符

    3.|:或

例:提示用户输入信息,然后判断用户输入的信息是否合法;

#!/bin/bash
#
read -p "Please make your choice[yes of no]: " CHOICE
case $CHOICE in
    yes|YES)
        echo "right."
        ;;
    NO|no)
        echo "wrong."
        ;;
    *)
        echo "Unknow."
        ;;
esac

if的分支结构和case的分支结构之间的区别:

    相同点:

        1.都是条件为真,执行对应分支的语句;条件为假,就不执行;

        2.都可以设置默认分支语句,即:所有条件都不匹配的时候,所执行的语句;

    不相同点:

        1.if是根据命令的执行状态返回值来判断正确与否;case是根据变量的值的取值内容是否匹配模式来判断正确与否;

        2.case的每个分支都必须使用“;;”结束;

while与until循环结构:

    while

        while 命令 ; do 命令 ;done

        while CONDITION ; do

            循环体

        done    

            进入循环条件:CONDITION一直为真

            退出循环条件:CONDITION为假

    until

        until 命令 ; do 命令 ; done

        until CONDITION ; do

            循环体

        done

            进入循环条件:CONDITION一直为假

            退出循环条件:CONDITION为假

其中:while CONDITION ; do CMD ; done 相当于 until ! CONDITION ; do CMD ; done

注意: 对于while和until两个循环结构来讲,如果要实施变量增量操作,必须手动给出;

例:利用while和until循环结构,计算100以内所有整数的和;

#!/bin/bash
#
declare -i I=1
while [ $I -lt 100 ] ; do
    let SUM+=$I
    let l++
done
echo $SUM

#!/bin/bash
#
declare -i I=1
until [ $I -gt 100 ] ; do
    let SUM+=$I
    let I++
done
echo $SUM

循环控制语句:

    continue   

    break

continue:

    continue [n]

    提前结束第n层的本次循环,直接进入下一轮条件判断,若符合循环进入条件,则开启下一轮循环;

break:

    break [n]

    提前结束第n层循环;不再继续后续循环;

无限循环用法:

    while true ; do

        循环体

    done

    until false ; do

        循环体

    done

在此类的循环结构中,必须适当的使用continue和break,以保证循环不会一直持续下去;

能够实现遍历功能的while循环;

while read LINES ; do

    循环体

done < /PATH/FROM/SOMEFILE

until ! read LINES ; do 

    循环体

done < /PATH/FROM/SOMEFILE

例:文件abc.txt内容如下:

1,2,3,5,6

b,d,g,h,e

6,3,7,1,7

f,g,e,y,a

写一个脚本,利用循环结构,输出每一行的第二个和第四个字符(以逗号分隔)

#!/bin/bash
#
while read LINES ; do
    echo -n $LINES | cut -d, -f2,4 | tr '\n' ','
done < abc.txt

select

    select循环只要用于创建一个菜单式列表,供用户进行选择;

    列表是按照数字顺序排列的,我们只要选择数字即可;

    一般来讲,select与case一起使用;

    seelcet是一个无限循环结构,因此,必须在循环体中使用break命令以退出循环,或者可以使用exit命令直接终止脚本运行;

    select NAME [in 词语 ...; ] do 命令 ; done

    select NAME [in LIST] ; do

        命令

    done

例子:

#!/bin/bash
#
select | in meat soap rice vag ; do
    case $I in
        meat)
            echo "I like it."
            break
            ;;
        soap)
            echo "I don't like it."
            continue
            ;;
        *)
            exit
   esac
done

shell脚本编程之函数

systemV风格的服务管理脚本:

    给脚本传递一些参数:start,stop,restart,status

    例:#ssh username@IP

把那些在脚本中重复出现并且没有任何改变的代码,封装起来,在适当的场景中调用执行;

程序员将这种被封装起来的代码称为功能提,或者叫模块;

function -- 函数

在shell脚本编程中,函数是由若干条shell命令组成的语句快,通常用于代码重用和模块化封装;

函数里面的内容和shell程序形式上是一致的;不同之处就是,shell代码可以直接被执行;而函数中的内容,不能独立执行,只有被调用的时候才被执行;

函数是在shell程序的当前shell中运行的;

定义函数:

    函数是由两部分组成:函数名称+函数体(能够实现独立功能的shell语句块)

    语法一:

        function func_name{

            函数体

        }

    语法二:

        func_name(){

            函数体

        }

    注意:函数名和()之间不能有空白字符;

函数的使用:

    函数在定义的时候,其函数体中包含的所有命令均不会被执行,只有函数被调用的时候,才会执行其中的命令语句;

    调用方式:通过直接给出函数名称的方式调用;

有很多的函数是存放与专门用于保存函数的文件中,如果想要调用这样的文件中保存的函数,使用source命令(.)加载文件,然后再以直接给出函数名称的方式调用函数;

使用set命令可以查看所有当前shell中国生效的函数;

使用unset命令可以撤销已经定义的函数;

函数的返回值:

    两种返回值:

        函数的执行结果的返回值:

            1.在函数体中使用了echo或printf命令输出结果;

            2.在函数体中某些命令输出的结果;

        函数的状态返回值:

            1.函数中最后一跳命令的执行状态返回值;

            2.自定义退出状态码;

                return [n]

                    n:0-255(1 2 127尽可能不适用)

                    0:表示无错误返回

                    1-255:有错误返回

                注意:只要函数在执行是,遇到了return命令,不管函数中的命令语句是否全部执行完成,立刻退出函数;

函数的声明周期:

    从被调用开始,到遇到return命令或全部的语句执行完成为止;

函数的实参:

    在函数体中,可以使用$1,$2,...位置变量为函数提供参数;还可以使用$*或$@的方式引用所有位置参数;还可以使用$#计算为函数传递的参数个数;

    在调用函数的时候,直接在函数名称后面以空白字符分隔多个参数即可;

    比如: func_name arg1 arg2 ...

例子:

#!/bin/bash
#
addusers(){
    for I in {1..5} ; do
        if id $1$I &> /dev/null | ; then
            echo "User $1$I exists."
            return 5
        else
            useradd $1$I &> /dev/null
            echo $1$I | passwd --stdin $1$I
            echo "Create user $1$I funished."
        fi
    done
}
addusers $1

    传递给函数的位置参数,是调用函数的时候,函数名称后面的有空白字符分隔的字符串序列;跟脚本的位置参数不是一回事;

变量:

    shell中的变量为弱变量

        1.无需事先声明

        2.无需指定变量类型,默认为字符型

    变量分类:

        环境变量: 当前shell及子shell

        本地变量: 当前shell

        局部变量: local VAR_NAME=VALUE当前函数体

        位置变量:

        特殊变量:

建议:手动销毁自己定义或声明的所有变量;

函数的递归调用

    简单来说,就是在函数体中调用函数自身;

例:阶乘:N!=N*(N-1)!=N*(N-1)*(N-2)!=...=N*(N-1)*(N-2)*...*2*1

#!/bin/bash
#
fact(){
    if [ $1 -eq 0 ] || [ $1 -eq 1 ] ; then
        echo 1
    else
        echo "$[$1*$(fact $[$1-1])]"
        fi
}
ehco -n "$1!="
fact $1


文章名称:我的朗科运维第八课
本文路径:http://scyanting.com/article/ggejho.html