温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

bash脚本编程的语法知识点总结第二部分

发布时间:2020-07-29 02:36:21 来源:网络 阅读:228 作者:heroleilei0627 栏目:网络安全

bash脚本编程的语法知识点总结第二部分

承接第一部分进行总结分析

6.bash编程之交互编程

    read

        -p"prompt" //提示

        -ttimeout

    给变量默认值

    varName=${varName:-value}

       如果varName不空,则返回varName的值;否则varName会使用value作为其值

    使用read参数[-p]后,允许在[-p]后面跟一字符串,在字符串后面跟n个shell变量。n个shell变量用来接收从shell界面输入的字符串

    [-p]用法:read –p “string” var1 var2…varn

   

练习:通过键盘给定一个文件的路径,来判定文件内容类型

    #!/bin/bash

    read –p “Enter a file name:” fileName

    type $fileName

   

    通过键盘给定一个路径,默认为/,来判定目录下文件内容类型

   

     例如:输入用户名,可返回其shell

        #!/bin/bash

        #

        read-p "Plz input a username: " userName

   

        ifid $userName &> /dev/null; then

            echo "The shell of $userName is `grep"^$userName\>" /etc/passwd | cut -d: -f7`."

        else

            echo "No such user. stupid."

        Fi

   

    例子:显示一个如下菜单给用户:

        cpu)show cpu infomation

        mem)show memory infomation

        *)quit

   

        1、如果用户选择了cpu,则显示/proc/cpuinfo文件的内容;

        2、如果用户选择了mem,则显示/proc/meminfo文件的内容;

        3、退出

   

           #!/bin/bash

           #

           echo"---------menu----------"

           echo"cpu) show cpu infomation"

           echo"mem) show memory infomation"

           echo"*) quit"

           echo"-------menu------------"

   

           read-p "Plz give your choice: " choice

   

           if[ "$choice" == 'cpu' ]; then

               cat /proc/cpuinfo

           elif[ "$choice" == 'mem' ]; then

               cat /proc/meminfo

           else

               echo "Quit"

               exit 3

           fi

   

   

    在第二个EOF前不要有换行、制表符或者空格

           #!/bin/bash

           #

           cat<< EOF

           -------menu------------

           cpu)show cpu infomation

           mem)show memory infomation

           *)quit

           -------menu------------

           EOF

   

           read-p "Plz give your choice: " choice

   

           if[ "$choice" == 'cpu' ]; then

               cat /proc/cpuinfo

           elif[ "$choice" == 'mem' ]; then

               cat /proc/meminfo

           else

               echo "Quit"

               exit 3

           fi

 

 

7.bash编程之函数

    语法:

    function F_NAME {

      函数体

    }

  

    F_NAME() {

      函数体

    }

    可调用:使用函数名

      函数名出现的地方,会被自动替换为函数;

  

    脚本:

    函数的返回值

      函数的执行结果返回值:代码的输出

        函数中的打印语句:echo, print

        函数中调用的系统命令执行后返回的结果

  

      执行状态返回值

        函数体中最后一次执行的命令状态结果

        自定函数执行状态的返回值:return #

  

    函数可以接受参数:

      在函数体中调用函数参数的方式同脚本中调用脚本参数的方式:位置参数

        $1, $2, ...

        $#, $*, $@

 

    示例:服务脚本示例

     #!/bin/bash

     #

     # chkconfig: 2345 67 34

     #

     srvName=$(basename $0)

     lockFile=/var/lock/subsys/$srvName

 

     start() {

         if [ -f $lockFile];then

        echo "$srvName is already running."

        return 1

       else

        touch $lockFile

        [ $? -eq 0 ] && echo "Starting $srvNameOK."

        return 0

          fi

     }

 

     stop() {

        if [ -f $lockFile];then

        rm -f $lockFile &> /dev/null

        [ $? -eq 0 ] && echo "Stop $srvName OK"&& return 0

         else

        echo "$srvName is not started."

        return 1

         fi

     } 

 

     status() {

         if [ -f $lockFile ];then

        echo "$srvName is running."

         else

        echo "$srvName is stopped."

         fi

         return 0

     }

 

     usage() {

          echo "Usage:$srvName {start|stop|restart|status}"

          return 0

     }

 

     case $1 in

     start)

        start

        ;;

     stop)

        stop ;;

     restart)

        stop

        start ;;

     status)

        status ;;

     *)

        usage

        exit 1 ;;

     esac

 

 

    练习:写一个脚本,完成如下功能(使用函数):

    1、提示用户输入一个可执行命令;

    2、获取这个命令所依赖的所有库文件(使用ldd命令);

    3、复制命令至/mnt/sysroot/对应的目录中

     解释:假设,如果复制的是cat命令,其可执行程序的路径是/bin/cat,那么就要将/bin/cat复制到/mnt/sysroot/bin/目录中,如果复制的是useradd命令,而useradd的可执行文件路径为/usr/sbin/useradd,那么就要将其复制到/mnt/sysroot/usr/sbin/目录中;

    4、复制各库文件至/mnt/sysroot/对应的目录中;   

    #!/bin/bash

    #

    target=/mnt/sysroot/

   

    [ -d $target ] || mkdir $target

   

    preCommand() {

        if which $1 &> /dev/null; then

     commandPath=`which--skip-alias $1`

     return0

        else

     echo"No such command."

     return1

        fi

    }

   

    commandCopy() {

        commandDir=`dirname $1`

        [ -d ${target}${commandDir} ] || mkdir-p ${target}${commandDir}

        [ -f ${target}${commandPath} ] || cp $1${target}${commandDir}

    }

   

    libCopy() {

        for lib in `ldd $1 | egrep -o"/[^[:space:]]+"`; do

     libDir=`dirname$lib`

     [ -d${target}${libDir} ] || mkdir -p ${target}${libDir}

     [ -f${target}${lib} ] || cp $lib ${target}${libDir}

        done

    }

    

    read -p "Plz enter a command: "command

   

    until [ "$command" == 'quit' ];do

   

      if preCommand $command &>/dev/null; then

        commandCopy $commandPath

        libCopy $commandPath

      fi

   

      read -p "Plz enter a command: "command

    done

 

 

8.bash编程之信号捕捉

   信号种类

   1) SIGHUP本信号在用户终端连接(正常或非正常)结束时发出,通常是在终端的控制进程结束时,通知同一session内的各个作业,这时它们与控制端不再关联。

   2) SIGINT程序终止(interrupt)信号,在用户键入INTR字符(通常是Ctrl-C)发出

   3) SIGQUIT和SIGINT类似,但由QUIT字符(通常是Ctrl-/)来控制。进程在因收到SIGQUIT退出时会产生core文件,在这个意义1类似于一个程序错误信号。

   4) SIGILL执行了非法指令,通常是因为可执行文件本身出现错误,或者试图执行数据段。堆栈溢出时也有可能产生这个信号

    trap命令用于在shell程序中捕捉到信号,之后可以有三种反应方式:

    (1)执行一段程序来处理这一信号

    (2)接受信号的默认操作

    (3)忽视这一信号

    trap对上面三种方式提供了三种基本形式:

    第一种形式的trap命令在shell接收到signallist清单中数值相同的信号时,将执行双引号中的命令串。

    trap 'commands' signal-list

    trap "commands" signal-list

    第二种形式的trap命令恢复信号的默认操作:trap signal-list

    第三种形式的trap命令允许忽视信号:trap " " signal-list

    trap 'COMMAND' SIGINT(表示关闭进程)

   

    例:写一个脚本,能够ping探测指定网络内的所有主机是否在线,当没有执行完时可接收ctrl+c命令退出。

    #!/bin/bash

    

    quitScript() {

         echo "Quit..."

    }   

    trap 'quitScript; exit 5' SIGINT

    

    cnetPing() {

        for i in {1..254}; do

            if ping -c 1 -W 1 $1.$i &>/dev/null; then

                echo "$1.$i is up."

             else

                echo "$1.$i is down."

            fi

            done

    }

    

    bnetPing() {

        for j in {0..255}; do

            cnetPing $1.$j

        done

    }

    

    anetPing() {

        for m in {0..255}; do

            bnetPing $1.$m

        done

    }

    

    netType=`echo $1 | cut -d"." -f1`

    

    if [ $netType -ge 1 -a $netType -le 126 ];then

        anetPing $netType

    elif [ $netType -ge 128 -a $netType -le 191]; then

        bnetPing $(echo $1 | cut -d'.' -f1,2)

    elif [ $netType -ge 192 -a $netType -le 223]; then

        cnetPing $(echo $1 | cut -d'.' -f1-3)

    else

        echo "Wrong"

        exit 2

    fi

   

 

9.bash编程之数组

9.1 数组定义

    数组:连续的多个独立内存空间,每个内存空间相当于一个变量

    数组元素:数组名+索引(从0开始编号)

 

     索引的表示方式:

          数字索引:a[index]

          a[0], a[1]

 

        bash 4.0的关联数组

          a[hello], a[hi]

 

     声明数组:declare -a ARRAR_NAME

     关联数组:declare -A ARRAY_NAME

     支持稀疏格式:仅一维数组

 

   数组的赋值:

       (1)一次对一个元素赋值:

          a[0]=$RANDOM

        ...

        echo ${a[0]}

       

       (2)一次对全部元素赋值:

          a=(red blue yellowgreen)

 

    一对括号表示是数组,数组元素用“空格”符号分隔开。

 

       (3)按索引进行赋值:

          a=([0]=green [3]=red[2]=blue [6]=yellow)

 

       (4)命令替换:

         logs=($(ls /var/log/*.log))

        或者logs=(/var/log/*.log)

         echo ${logs[0]}

 

       (5)用户输入

          read -a ARRAY

 

    数组的访问:

     用索引访问:ARRAY[index]

 

     数组的长度

     ${#ARRAY[*]}

     ${#ARRAY[@]}

    eg:echo ${#test[*]}

       echo ${#test[@]}

 

     练习:写一个脚本,生成10个随机数,保存至数组中;而后显示数组下标为偶数的元素;

     #!/bin/bash

     for i in {0..9};do

         num[$i]=$RANDOM

         if [ $[$i%2] -eq 0];then

            echo "a[i] is${a[i]}"

         fi

     done

    

     从数组中挑选某元素:

     ${ARRAY[@]:offset:number}

        切片:

          offset: 偏移的元素个数

           number: 取出的元素的个数

 

     ${ARRAY[@]:offset}:取出偏移量后的所有元素

     ${ARRAY[@]}: 取出所有元素

 

 

    数组复制:

     要使用${ARRAY[@]}

 

     $@: 每个参数是一个独立的串

     $*: 所有参数是一个串

 

   向数组追加元素:非稀疏格式

   mylogs,

   mylogs[${#week[@]}]

  

   示例:复制一个数组中下标为偶数的元素至一个新数组中

        #!/bin/bash

        declare -a mylogs

        logs=(/var/log/*.log)

 

        echo ${logs[@]}

 

        for i in `seq 0 ${#logs[@]}`; do

            if [ $[$i%2] -eq 0];then

               index=${#mylogs[@]}

              mylogs[$index]=${logs[$i]}

            fi

        done

 

        echo ${mylogs[@]}

 

    从数组中删除元素:unset ARRAY[index]

 

     练习1:生成10个随机数,升序排序

     #!/bin/bash

     for((i=0;i<10;i++))

     do

        rnd[$i]=$RANDOM

     done

 

     echo -e "total=${#rnd[@]}\n${rnd[@]}\nBegin to sort"

 

     for((i=9;i>=1;i--))

     do

        for((j=0;j<i;j++))

        do

          if [ ${rnd[$j]} -gt${rnd[$[$j+1]]} ] ;then

            swapValue=${rnd[$j]}

            rnd[$j]=${rnd[$[$j+1]]}

            rnd[$[$j+1]]=$swapValue   

          fi

        done

     done

 

     echo ${rnd[@]}

    

    练习2:打印九九乘法表

 

     #!/bin/bash

     for((i=1;i<=9;i++))

     do

        strLine=""

        for((j=1;i<=9;j++))

        do

          strLine=$strLine"$i*$j="$[$i*$j]"\t"

          [ $i -eq $j ] && echo -e $strLine && break

        done

     done

 

 

9.2bash编程之字符串操作

    字符串切片:

     ${string:offset:length}

 

     取尾部的指定个数的字符:

      ${string: -length}

   

     取子串:基于模式

      ${variable#*word}:在variable中存储字串上,自左而右,查找第一次出现word删除字符开始至此word处的所有内容

      ${variable##*word}:在variable中存储字串上,自左而右,查找最后一次出现word删除字符开始至此word处的所有内容

        file='/var/log/messages'

           ${file#*/}: 返回的结果是var/log/messages

           ${file##*/}: 返回messages

   

      ${variable%word*}: 在variable中存储字串上,自右而左,查找第一次出现word,删除此word处至字串尾部的所有内容

      ${variable%%world*}:在variable中存储字串上,自右而左,查找最后一次出现word删除此word处至字串尾部的所有内容

        file='/var/log/messages'

           ${file%*/}: 返回的结果是/var/log

           ${file%%*/}: 返回结果为空

   

        phonenumber='010-110-8'

           ${phonenumber%%-*}

           ${phonenumber##*-}

   

        url="http://www.magedu.com:80"

        取端口:${url##*:}

        取协议:${url%%:*}

          

     查找替换:

      ${variable/pattern/substi}: 替换第一次出现

      ${variable//pattern/substi}:替换所有的出现

   

      ${variable/#pattern/substi}:替换行首被pattern匹配到的内容

      ${variable/%pattern/substi}:    行尾

   

      pattern可以使用globbing中的元字符:

        *

        ?

   

     查找删除:

      ${variable/pattern}

      ${variable//pattern}

      ${variable/#pattern}

      ${variable/%pattern}

   

     大小写转换:

      小-->大:${variable^^}

      大-->小:${variable,,}

    只能对变量的单个字符做操作,eg:echo ${user^^a}

 

 

    变量赋值操作:

    ${parameter:-word}

              Use  Default Values.  If parameter is unset ornull, the expansion of word is substituted. Otherwise, the value of parameter is

              substituted.

    ${parameter:=word}

          Assign Default Values.  If parameter is unset or null, the expansionof word is assigned to parameter.  Thevalue of parameter is

          then substituted.  Positional parameters and special parametersmay not be assigned to in this way.

    ${parameter:?word}

          Display Error if Null or Unset.  If parameter is null or unset, the expansionof word (or a message to that effect if word is not

          present) is written to the standarderror and the shell, if it is not interactive, exits.  Otherwise, the value of  parameter is

          substituted.

    ${parameter:+word}

          Use Alternate Value.  If parameter is null or unset, nothing issubstituted, otherwise the expansion of word is substituted.

 

    ${variable:-string}

     variable为空或未设定,那么返回string,否则,返回variable变量的值;

 

    ${variable:=string}

     variable为空或未设定,则返回string,且将string赋值给变量variable,否则,返回variable的值;

 

 

    为脚本使用配置文件,并确保某变量有可用值的方式

     variable=${variable:-defaultvaule}

     eg:

     [ -f etc/sysconfig/test ] &&source /etc/sysconfig/test

     myvar=${myvar:-www.mageedu.com}

     echo $myvar

     练习:读取/etc/sysconfig/network文件,利用其HOSTNAME变量的值设置主机名;

 

9.4 bash编程之补充

 

    mktemp命令:

    mktemp [OPTIONS] filename.XXX

 

    -d: 创建临时目录

    --tmpdir=/path/to/somewhere :指定临时文件所在的目录

 

    mktemp /tmp/tmp.XXX                    #XXX生成相同数量随机字符

    mktemp --tmpdir=/var/tmp tmp.XXX       #指定目录创建临时文件

mktemp --tmpdir=/var/tmp -d tmp.XXX    #指定目录创建临时目录

 

    install命令:

    install [OPTIONS] SOURCE DEST

    install [OPTIONS] SOURCE... DIR

    install [OPTIONS] -d DIR ...

    增强型的复制命令:

 

    -o OWNER

    -g GROUP

    -m MODE

   

    -d : 创建目录

 

    install /etc/fstab /tmp                 #复制文件到指定目录

    install --mode=644 /etc/fstab /tmp/     #复制时指定权限

    install --owner=scholar /etc/fstab /tmp #复制时指定属主

    install --group=scholar /etc/fstab /tmp #复制时指定属组

    install -d /tmp/install                 #创建目录


向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI