美文网首页
bash 脚本进阶

bash 脚本进阶

作者: 一桥长书 | 来源:发表于2017-09-03 16:21 被阅读0次

    1 流程控制

    过程式编程语言
      顺序执行
      选择执行
      循环执行
    
    顺序执行
      按照脚本的由上到下,一步步执行,直到结束
    选择执行
      通过条件判断,执行相应的代码,如if,case
    循环执行
      通过一定的条件,循环执行某些命令,如for ,while,until
    
    1.编写脚本/root/bin/createuser.sh ,实现如下功能:使
    用一个用户名做为参数,如果指定参数的用户存在,就显示
    其存在,否则添加之;显示添加的用户的id 号等信息
    #!/bin/bash
    read -p "please input a username: " user
    if id $user;then
        echo "user is exists"
        exit 
    else
        useradd $user &>/dev/null
        password=`openssl rand -hex 4`
    # 将生成的密码记录下来
        echo $user:$password >>./password.log 
        echo $password | passwd --stdin $user &>/dev/null
    fi
    2.写脚本/root/bin/yesorno.sh ,提示用户输入yes 或no,
    并判断用户输入的是yes 还是no, 或是其它信息
    #!/bin/bash
    read  -p "input answer: " answer
    answer=`echo $answer| tr '[:upper:]' '[:lower:]'`
    case $answer in
    t|true|y|yes)
        echo yes
        ;;
    f|false|n|no)
        echo no
        ;;
    *)
        echo invalid
    esac
    3.写脚本/root/bin/filetype.sh, 判断用户输入文件路径
    ,显示其文件类型(普通,目录,链接,其它文件类型)
    #!/bin/bash
    read -p "please input a path: " path
    [ ! -e $path ] && echo "file is not exists" && exit 1
    [ -h $path ] && echo "it is link" && exit
    [ -f $path ] && echo "it is common file " &&exit
    [ -d $apth ] && echo "it is directory" && exit
    4.编写脚本/root/bin/checkint.sh, 判断用户输入的参数是
    否为正整数
    #!/bin/bash
    read -p "input a num: " num
    [ $num -gt 0 -o `expr 0 + $num` ] && echo it's a +num
    
    for
    1.判断/var/ 目录下所有文件的类型
    #!/bin/bash
    for file in /var/*;do
        /usr/bin/file $file
    done
    2 .添加10 个用户user1-user10 ,密码为8 位随机字符
    #!/bin/bash
    for user in user{1..10};do
        if id $user &>/dev/null;then
        echo "$user is exits"
        else
        useradd $user
        password=`openssl rand -hex 4`
        echo $user:$password
        echo "$password" | passwd --stdin $user &>/dev/null
        fi
    done
    3./etc/rc.d/rc3.d 目录下分别有多个以K 开头和以S 开头的文件;分别读取每个文件,以K 开头的输出为文件加stop ,以S 开头的输出为文件名加start ,如K34filename stop S66filename start
    #!/bin/bash
    for file in /etc/rc.d/rc3.d/*;do
        file=$(basename $file)
        if [[ $file =~ ^K ]];then
        echo "$file stop"
        elif [[ $file =~ ^S ]];then
        echo "$file start"
        else 
        echo "nothing to do"
        fi
    done
    4.编写脚本,提示输入正整数n 的值,计算1+2+…+n 的总和
    #!/bin/bash
    read -p "input a num: " num
    #let sum=($num+1)*$num/2
    a=`expr $num + 1`
    b=`expr $a \* $num`
    sum=`expr $b \/ 2`
    echo $sum
    5.计算100 以内所有能被3 整除的整数之和
    #!/bin/bash
    read -p "input a num: " num
    #echo `seq 0 3 $num` | tr " " "+" | bc
    #echo {0..100..3} | tr " " "+" | bc
    declare -i sum=0
    for i in `seq 0 3 $num`;do
        if [ `expr $i % 3` -eq 0 ];then
        let sum+=$i
        fi
    done
    echo $sum
    6 .打印九九乘法表
    #!/bin/bash
    declare -i I=1
    declare -i sum=0
    while [ $I -le 9 ];do
        declare -i J=1
        while [ $j -le $i ];do
            let sum=$j*$i
    #       if [ $I -le 4 -a $J -eq 3 ];then
    #           echo -n " "
    #       fi
    #       if [ $I -ne $J ];then
                echo -ne "$J*$I=$sum\t"
    #       else
    #           echo  "$J*$I=$sum"
    #       fi
            let J++
        done
        echo 
        let I++
    done
    7 .在/testdir 目录下创建10 个html 文件, 文件名格式为数字N (从1 到10 )加随机8 个字母,如:1AbCdeFgH.html
    #!/bin/bash
    for i in {1..10};do
        random=`tr -dc '[:alnum:]' < /dev/urandom|head -c 8`
        touch ${i}${random}.html
    done
    
    1 每隔3 秒钟到系统上获取已经登录的用户的信息;如果发
    现用户hacker 登录,则将登录时间和主机记录于日志
    /var/log/login.log 中, 并退出脚本
    #!/bin/bash
    a=` w | awk -F" " '$1=="hacker"{print $1,$3}'`
    while : do
    [ `wc -l ` -ge 1 ]&& echo $a >>/var/log/login.log
    sleep 3
    done       
    

    2 函数

    函数变量
      环境变量:当前shell 和子shell 有效
      本地变量:只在当前shell 进程有效,为执行脚本会启动专用子shell 进程;因此,本地变量的作用范围是当前shell 脚本程序文件,包括脚本中的函数
      局部变量:函数的生命周期;函数结束时变量被自动销毁
      注意:如果函数中有局部变量,如果其名称同本地变量,使
    用局部变量
    
    函数有两种返回值:
      函数的执行结果返回值:
        (1)  使用echo 等命令 进行输出
        (2)  函数体中调用命令的输出结果
      函数的退出状态码:
        (1)  默认取决于函数中执行的最后一条命令的退出状态码
        (2)  自定义退出状态码, 其格式为:
          return 从函数中返回,用最后状态命令决定返回值
          return 0 无错误返回。
          return 1-255 有错误 返回
    
    编写函数,实现OS 的版本判断
    #!/bin/bash
    get_ver (){
        return `sed -r "s@.* ([0-9])\..*@\1@" /etc/redhat-release`
    }
    get_ver
    echo $?
    编写函数,实现取出当前系统eth0 的IP 地址
    #!/bin/bash
    get_ip (){
       a=`ip addr show eth0 | sed -rn  "s@.*inet (.*)/.*@\1@p"`
       export a
    }
    get_ip
    echo $a
    编写函数,实现打印绿色OK 和红色FAILED
    echo_ok(){
       echo -en "$1\\033[60G[";echo -en "\\033[1;32m";echo -en "   ok   ";echo -en "\\033[0;39m]\n"
    }
    echo_fail(){
        echo -en "$1\\033[60G[";echo -en "\\033[1;31m";echo -en " failed ";echo -en "\\033[0;39m]\n"
    }
    [ 1 -eq 0 ] || echo_fail "1=0" 
    [ 1 -eq 1 ] && echo_ok "1=1"
    
      编写脚本/root/bin/copycmd.sh
    (1)  提示用户输入一个可执行命令名称
    (2)  获取此命令所依赖到的所有库文件列表
    (3)  复制命令至某目标目录( 例如/mnt/sysroot) 下的对应路径下;   如:/bin/bash ==> /mnt/sysroot/bin/bash
    /usr/bin/passwd ==> /mnt/sysroot/usr/bin/passwd
    (4)  复制此命令依赖到的所有库文件至目标目录下的对应路径下 如:/lib64/ld-linux-x86-64.so.2 ==>/mnt/sysroot/lib64/ld-linux-x86-64.so.2
    (5) 每次复制完成一个命令后,不要退出,而是提示用户键入新的要复制的命令,并重复完成上述功能;直到用户输入quit 退出
    
    target=/app
    read -p "please input a cmd(eg:ls): " cmd
    until [ "$cmd" == "quit" ];do
        pcmd=`which --skip-alias $cmd`
        [ -e $target$pcmd ] && { echo $cmd is exists;read -p "please input a cmd(eg:ls): " cmd;continue; }
        cmdpath=`dirname $pcmd`
        [ -d $target$cmdpath ] || mkdir -p $target$cmdpath
        [ -e $target$pcmd ] || cp $pcmd $target$cmdpath
        #for i in `ldd $pcmd |egrep -o "/.*[[:space:]]+"`;do
        for i in `ldd $pcmd | sed -rn "s@[^/]*(/.*)[[:space:]].*@\1@p"`;do
        #for i in `ldd $pcmd | egrep -o "/.*\.[^[:space:]]+"`;do
        libdir=`dirname $i`
        [ -d $target$libdir ] || mkdir -p $target$libdir
        [ -e $target$i ] || cp $i $target$libdir
        done
        read -p "please input a cmd(eg:ls): " cmd
    done
    
    斐波那契数列又称黄金分割数列,因数学家列昂纳多· 斐波那契以兔子繁殖为例子而引入,故又称为“兔子数列”,指的
    是这样一个数列:0 、1 、1 、2 、3 、5 、8 、13 、21 、34、 、…… ,斐波纳契数列以如下被以递归的方法定义:F (0 )=0, F (1 )=1 ,F (n )=F(n-1)+F(n-2) (n≥2) )利用函数,求n阶菲波那切数列
    #!/bin/bash
    fab(){
        if [ $1 -eq 0 ];then
        echo 0
        elif [ $1 -eq 1 ];then
        echo 1
        else
        echo $[`fab $[$1-1]`+`fab $[$1-2]`]
        fi
    }
    read -p "onput a num > 0 (eg:10): " num
    fab $[$num-1] 
    

    3 数组

    引用数组元素:
      ${ARRAY_NAME[INDEX]}
      注意:省略[INDEX] 表示引用下标为0 的元素
    引用数组所有元素:
      ${ARRAY_NAME[*]}
      ${ARRAY_NAME[@]}
    数组的长度( 数组中元素的个数): :
      ${#ARRAY_NAME[*]}
      ${#ARRAY_NAME[@]}
    删除数组中的某元素:导致稀疏格式
      unset ARRAY[INDEX]
    删除整个数组 :
      unset ARRAY
    数组切片:${ARRAY[@]:offset:number}
        offset:  要跳过的元素个数
        number:  要取出的元素个数
    取偏移量之后的所有元素
        ${ARRAY[@]:offset}
    向数组中追加元素:
      ARRAY[${#ARRAY[*]}]=value
    
    1.输入若干个数值存入数组中,采用冒泡算法进行升序或降序排序
    #!/bin/bash
    declare -i tmp
    declare -a c
    c=(`for i in $(seq 1 10);do echo $RANDOM ;done`)
    echo ${c[*]}
    
    for I in $(seq 1 ${#c[*]});do
        for J in $(seq $I $[${#c[*]}-1]) ;do
            if [ ${c[$[$I-1]]} -gt ${c[$J]} ];then
    #           echo ${c[$[$I-1]]} $[$I-1]  ${c[$J]} $J
                tmp=${c[$[$I-1]]}
                c[$[$I-1]]=${c[$J]}
                c[$[$J]]=$tmp
            fi
        done
    done
    echo ${c[*]}
    unset tmp
    unset c
    

    相关文章

      网友评论

          本文标题:bash 脚本进阶

          本文链接:https://www.haomeiwen.com/subject/hthjjxtx.html