首页 > 代码库 > Bash变成(二)

Bash变成(二)

一、Bash脚本编程风格
二、Bash条件测试:
三、脚本的状态返回值       
四、练习脚本:
五、if 语句

一、Bash脚本编程风格
    脚本格式:
    #!/bin/bash
    #description: say hello
    #version 0.0.1        //注释信息    
    #author:xiaoming        //代码注释
    #date:2017-01-01
    
    缩进:适度添加空白行;
    
    语法:编程语法格式、库调用(类库)、算法、数据结构
    
    编程思想:
        问题空间-->解空间
    变量:
        局部变量:当前shell
        本地变量:local,函数内部
        环境变量:当前shell及其子进程
        位置参数变量:$1,$2,$3
        特殊变量:$#,$@
    变量的数据类型://弱类型,默认都为字符型
        字符型
        数值型
        
    算数运算:+,-,*,/,%,**
        expr,let
        let VAR=expression
        $((expression))
        $[expression]
        var=$(expr argu1 + argu2)  //一个小括号,命令引用
        
    注意:有些时候,乘法符号需要转义    
    animal=dog;echo "${animal}s" //用花括号分开即可
    PATH=“$PATH:/usr/locale/apache/bin" //引用原有的值,然后重新赋值
    
    增强型赋值:变量做某种算术运算后回至此变量中
        declare -i a=1 //
        i=$[$i+1]
        let i+=2 //这样也可以的:增强型复制机制
        let +=,-=,*=,/=,%=  //一般使用let进行
        let ++,--  //自己加上/减去 1
            let var=$[$var+1]
            let var+=1
            let var++
脚本1:添加user1
    #!/bin/bash
    # first_scrpit
    id user1 &> /dev/null || useradd user1
    id user2 &> /dev/null || useradd user2

    user_id1=$(id -u user1)
    user_id2=$(id -u user2)
    id_sum=$[$user_id1+$user_id2]
    echo "sum is :$id_sum"
    
练习:
    1.写一个脚本,计算/etc/passwd文件中第10个用户和第20个用户的id号之和
    2.计算/etc/rc.d/init.d/functions和/etc/inittba文件的空白行数之和
    1.
        id1=$(head -10 /etc/passwd | tail -1 | cut -d: -f3}
        id2=$(head -20 /etc/passwd | tail -1 | cut -d: -f3}
    2.
        b1=$(grep "^$" /etc/rc.d/init.d/functions  | wc -l)
        b1=$(grep "^[[:space:]]*$" /etc/rc.d/init.d/functions  | wc -l)
        
二、Bash条件测试:
    判断某需求是否满足,需要测试机制来实现
    ||,&&,! //或,非,与
    测试方法:
        1.执行命令,并利用命令状态返回值来判断
            0:成功
            1-255:失败
            echo $?
        2.测试表达式
            test -[d,e,f,h,p,r,s,S,w,N] a.txt
                d目录,f普通文件,e存在,h|-L符号文件,
                r可读,w可写,-s非空,-S套接字,-N上次读取之后修改过
            [ expression ]
            [[ expression ]]
            
            注意:expression两端必须有空格,否则为语法错误
    
    bash测试类型:
        数值测试
        字符串测试
        文件测试
        
    1.数值测试:数值比较
        -eq,-gt,-lt
        -ge,-le,-ne
            test 3 -gt 4 && echo True || echo false    
    2.字符串测试:根据ascii表,尽可能定义在[[ ]]中
        == 是否相当
        >         
        《    
        !=    是否不等于
        =-  :左侧的字符串是否能够被右侧的pattern匹配
            name=tom; [[ "$name" =~ t ]] ;echo $? //tom是否包含 t字母
        
        //单目
        -z “STRING” 判断子串是否为空,空则为真,否则为假
        -n “STRING” 是否不空
            [ -n "$name" ];echo $?
        注意:[[ “a” > “b” ]] ;echo $?
            //一定要使用两个中括号,否则会出错
            (1)字符串要加引用
            (2)要使用[[ ]]
    3.文件测试
        d目录,-S套接字,-p 管道文件
        f普通文件,
        a|e存在,
        h|-L符号文件,
        -b 块设备文件
        -s非空,
        -N上次读取之后修改过 //上次读取后,是否被修改过
        
    4.文件权限测试:
        r可读,是否存在且对当前用户可读
        w可写,
        x可执行    
        -g 是否存在,并且拥有sgid权限
        -u 是否存在,并且拥有suid权限
        -k sticky权限
            [ -u /bin/passwd ] ; echo $?
    5.从属关系测试
        -O FILE 当前用户是否为文件的属主
        -G FILE 当前用户是否为屋内安的属组
        
    6.双目运算
        FILE1 -ef FILE2 //file1与file2是否指向同一个fs的相同inode
        file1 -nt filr2 //file1是否新于file2
        file1 -ot file2 //file1是否旧于file2
        
    7.组合测试:
        逻辑运算:
            第一种方式:
                a && b
                a || b
                ! a //取反
        [ -O file ] && [ -r file ] //当前用户为属主并且可读
        [ -O file -a -x file ]
        
        expression -a expression2 //
        expression -o expression2
        ! expression

        test "a" != "$HOME" -a 3 -ge 4 ; echo $?
        [ ! \( "a" = "$HOME" -o 3 -lt 4 \) ]; echo $?
        [ ! \( "a" = "$HOME" -o ‘(‘ 3 -lt 4 ‘)‘ ")" ]; echo $?
    
三、脚本的状态返回值
    默认是脚本中执行的最后一条命令的状态返回值
    自定义状态返回值
    exit [n] //自定义状态返回值,状态码
    
    注意:shell进程遇到exit会终止,因此整个脚本将会结束
        一般判断条件是否满足,再执行exit
    
注意:XShell的锁定和接触锁定
    vim
    ctrl + s 锁定后,
    ctrl + q 取消锁定
    


四、练习脚本:

脚本1:
    将当前主机名称保存至hostName变量中:
    主机名为空,或者为localhost.localdomain,则将其设置为www.mt.com
#!/bin/bash
hostName=$(hostname)
[ -z "$hostName" -o "$hostName"=="localhost.localdomain" -o hostName=="localhost" ]  && hostname www.xt.com

注意:
    //必须是 [] ,而不能是 [[ ]] ,或者
    //== 前后不需要空格
    // [ ] 前后都需要空格,
    //$hostname 得需要“ ”    
    //[ ** -o|-a| ** ] 判断内部 // && ||  ! 判断[]外部
    
    
脚本2.向脚本传递参数
    位置参数变量;
    引用:
        $1,$2,...$(12)
    shift 轮替
        shift n :位置参数变量
    
    特殊变量:
        $0:脚本文件名
        $#: 获取参数个数总和
        $*: 所有参数
        $@: 所有参数

引用变量计算数值
bash sum.sh 23 78
#!/bin/bash
#
echo $[$1 + $2]

//判断文件空白行行数
#!/bin/bash
[ $# -lt 2 ] && echo "At least two files" && exit 1

b1=$(grep "^$" $1 | wc -l)
b2=$(grep "^$" $2 | wc -l)
echo "sum of blank is : $[b1+b2]"


五、if 语句

过程式编程语言的代码执行顺序
    顺序执行:逐条执行
    选择执行:
        代码有一个分支:条件满足则执行
            两个以上的分支:只会执行其中一个满足条件的执行
    循环执行:
        代码片段(循环体)要执行0,1或多个来回
        
    选择执行:
        if 测试条件 ; then  //需要分号
            代码分支
        fi
            
        if 测试条件        //then单独分行,不需要分号
        then
            代码分支
        fi
        
        双分支if语句
        if 测试条件; then
            条件为真时运行
        else
            条件为假时执行
        fi
        
脚本3:通过参数传递一个用户名给脚本,此用户不存在时添加该用户
#!/bin/bash
if [ $# -lt 1 ]; then
    echo "At least one user_name"
    exit 1
fi
if ! [ grep "$1\>" /etc/passwd ] &> /dev/null; then
    useradd $1
    echo $1 | passwd --stdin $1
    echo "USER $1 added succeed!"
    exit 0
else
    echo "Failure ..."
    exit1
fi

脚本4:通过键盘给定两个数字,输出其中较大的值
#!/bin/bash
#
if [ $# -lt 2 ] ; then
    echo "Two intergers."
    exit 2
fi
if [ $1 -ge $2 ] ;then
    echo "max number is: $1"
else
    echo "max number is: $2"
fi

脚本5:通过命令参数传递给定两个文件名,如果某文件不存在,则结束脚本
    返回每个文件的行数,并说明其中行数最多的文件
[root@wolf test]# cat 2.sh
#!/bin/bash
#AUthor xt
#date 2017-07-22
declare -i f1 f2
if [ $# -lt 2 ] ; then echo "At least two files " exit 1 ; fi
#if  [ ! -f $1 ] ||  [ ! -f $2 ] ; then
if  ! [ -f $1 -a  -f $2 ] ; then
    echo "At least one is not a primary file" exit 2 ;
else
    f1=$(wc -l $1 | cut -d‘ ‘ -f1)
    f2=$(wc -l $2 | cut -d‘ ‘ -f1)
    if [ $f1 -gt $f2 ] ;then
        max=$f1
    else
        max=$f2
    fi
    echo "First file‘s line is $f1"    
    echo "Second file‘s line is $f2"    
    echo "Max  is line is $max"    
fi
   

Bash变成(二)