天天看点

shell编程函数与数组

shell编程函数与数组

1、shell中函数

(1)shell中函数的语法

    语法一:

       函数名(){

          指令

         return n

      }

    语法二:

       function 函数名(){

           指令

           return n

       }

(2)shell中函数的调用执行

   1)直接执行函数名即可,在执行函数时,不要带小括号,函数定义及函数体必须要在执行的函数名前定义。

   2)带参数的函数的执行方法:函数名  参数1  参数2

(3)函数带参数的说明

   1)在函数体重,位置函数都可以是函数的参数

   2)父脚本的参数在函数中则临时地被函数参数所掩盖或隐藏

   3)$0比较特殊,他任然是父脚本的参数,

   4)在shell函数里面,return命令的工作方式与exit相同,用于跳出函数。

   5)在shell函数里使用exit会终止整个shell脚本。

   6)return语句会返回一个退出值给调用的程序

(4)递归:函数直接或间接的调用自身进行计算

   1)递归求阶乘

#!/bin/sh
function jc(){
  if [ $1 -eq 1 ]
    then
        echo "1"
   else
        echo $[ $1*$(jc $[$1-1]) ]
    fi
}
 
jc $1      

   2)递归求斐波那契数列第N项的值

#!/bin/bash
function ad(){
    if [ $1 -eq 1 ]
        then
        echo "1"
    elif [ $1 -eq 2 ]
        then
        echo "1"
    else
        echo $[ $(ad $[$1-1])+$(ad $[$1-2])]
    fi
}
 
ad $1      

2、数组

(1)数组:存储多个元素的连续内空间间,相当于多个变量的集合

(2)数组的创建与声明:

   1)定义一个数组:array=(“dayi123” 19)

   2)声明一个数组:

      声明索引数组:declare –a arrname

      声明关联数组:declare –A arrname

[[email protected] ~]#arr1=("dayi123" 13 "string")    #创建一个数组

[[email protected] ~]#declare -a arr2     #声明一个数组

[[email protected] ~]#arr2[0]="dayi"     #往数组中添加元素

[[email protected] ~]# arr2[1]="18"

(3)获取数组的长度

    echo ${#array[@]}

    echo ${#array[*]}

[[email protected] ~]# echo${#arr1[@]}  #打印数组中元素个数

3

[[email protected] ~]# echo${#arr2[*]}   #打印数组中元素个数

1

(4)打印数组的元素

    echo ${array[n]}

    echo ${array[@]}

    echo ${array[*]}

[[email protected] ~]# echo${arr1[1]}    #打印数组arr1中的第2个元素

13

[[email protected] ~]# echo${arr1[0]}    #打印数组arr1中的第1个元素

dayi123

[[email protected] ~]# echo${arr1[@]}   #打印数arr1中的所有元素

dayi123 13 string

[[email protected] ~]# echo${arr2[*]}    #打印宿主arr2中的所有元素

dayi123 22

(5)数组的赋值

   数组的赋值:array[3]=4

   修改数组元素:arrary[0]=”liuyi”

[[email protected] ~]#arr1[3]=4

[[email protected] ~]#arr1[0]="liu"

[[email protected] ~]# echo${arr1[*]}

liu 13 string 4

(6)数组内容的截取

   echo ${arr1[@]:n:m}      #截取第n个到第m个元素

[[email protected] ~]# echo${arr1[*]:1:2}

13 string

(7)数组内容的替换

   echo ${arr1[@]/n/m}      #将数组中的第一个n替换为m

[[email protected] ~]# echo${arr1[*]/"liu"/"dayi123"}

dayi123 13 string 4dayi123

(8)数组的删除与数组中元素的删除

   unset array   #删除整个数组

   unset array[n]  #删除数组中第n个元素,删除一个元素时只能从头开始一个一个删除

[[email protected] ~]# unsetarr1[0]  #删除数组中第一个元素

[[email protected] ~]# echo${arr1[*]}

13 4 liu

[[email protected] ~]# unsetarr1[2]   #直接删除数组中第二个元素,删不掉

[[email protected] ~]# echo${arr1[*]}

13 4 liu

[[email protected] ~]# unsetarr1[1]   #删除数组中第一个元素,因为第0个元素已经删除

[[email protected] ~]# echo${arr1[*]}

4 liu

[[email protected] ~]# unsetarr1     #删除整个数组

[[email protected] ~]# echo${arr1[*]}

[[email protected] ~]#

(9)数组使用案例:

   1)生成10个随机数,找出其中的最大值

#!/bin/sh
declare -a rand
declare -i max=0
for i in {0..9};do
        rand[$i]=$RANDOM
        echo ${rand[$i]}
        [ ${rand[$i]} -gt $max ] &&max=${rand[$i]}
done
 
echo "max is$max"      

         2)定义一个数组,数组中元素是/var/log目录下所有以.log结尾的文件,统计其下标为偶数的文件中的行数之和

#!/bin/sh
 
declare -a files
files=(/var/log/*.log)
declare -i lines=0
 
for a in $(seq 0$[${#files[*]}-1]);do
        if [ $[$a%2] -eq 0 ];then
            let lines+=$(wc -l ${files[$a]} |cut -d ' ' -f1)
        fi
done
echo"lines:$lines"      

3、变量字符串的操作

(1)获取长度

    echo ${#variable}

    echo $variable | wc –l

[[email protected] ~]#DAYI="i am dayi123"

[[email protected] ~]# echo${#DAYI}

12

[[email protected] ~]# echo$DAYI | wc -L

12

(2)截取字符串子串

    echo ${variable:n}        #从第n个字符开始截取

    echo ${variable:n:m}      #从第n个字符串始截取m个字符

    echo $variable | cut –c n-m  #从第n个字符开始截取m个字符

[[email protected] ~]# echo${DAYI:2}

am dayi123

[[email protected] ~]# echo${DAYI:2:5}

am da

[[email protected] ~]# echo$DAYI | cut -c 2-5

 am

(3)替换操作

    echo ${variable/char1/char2}    #将字符串中的char1替换为char2,只替换第一个

    echo ${variable//char1/char2}   #将变量中的所有字符串char1替换为char2

[[email protected] ~]#DAYI="dayi123DAYIdayi"

[[email protected] ~]# echo${DAYI/dayi/liu}     #将第一个dayi替换为liu

liu123DAYIdayi

[[email protected] ~]# echo${DAYI//dayi/liu}    #替换所有的dayi为liu

liu123DAYIliu

(4)删除操作

    echo ${variable#char1}     #从头开始删除匹配到的char1

    echo ${variable#a*c}       #删除第一次匹配到的a*c之间的内容

    echo ${variable##a*c}      #删除匹配到最长的a*c之间的内容

    echo ${variable%a*c}     #从结尾开始删除匹配到最短的a*c之间的内容

    echo ${variable%%a*c}    #从结尾开始删除匹配到最长的a*c之间的内容

[[email protected] ~]# echo$DAYI

dayi123DAYIdayi

[[email protected] ~]# echo${DAYI#dayi}    #删除第一个匹配到的dayi

123DAYIdayi

[[email protected] ~]# echo${DAYI#d*i}    #删除匹配到的d*i之间的内容

123DAYIdayi

[[email protected] ~]# echo${DAYI##d*i}  #删除匹配到的最长的d*i之间的内容

[[email protected] ~]# echo${DAYI%d*i}   #删除从结尾匹配到的d*i之间的内容

dayi123DAYI

[[email protected] ~]# echo${DAYI%%d*i}  #删除从结尾匹配到的最长的d*i的内容

[[email protected] ~]# echo${DAYI%%dayi}  #删除从结尾匹配到的dayi

dayi123DAYI

(5)字符的大小写替换

   echo ${variable^^}     #将变量中的小写字符替换为大写

   echo ${variable,,}       #将变量中的大写字符替换为小写

[[email protected] ~]# echo${DAYI^^}   

DAYI123DAYIDAYI

[[email protected] ~]# echo${DAYI,,}

dayi123dayidayi

(6)变量的测试

   ${variable:-char}  #如果变量存在且非空,则返回变量的值,否则返回char

   ${variable:=char}  #如果变量名存在且非空,则返回变量值,否则设置variable的值为char,并返回其值

   ${variable:+char}  #如果变量存在则返回CHAR,否则返回空值

[[email protected] ~]# echo${DAYI:=HELLO}   #变量DAYI存在,所以返回变量DAYI的值

dayi123DAYIdayi

[[email protected] ~]# echo${LIU:=HELLO}    #变量LIU不存在,所以返回HELLO,并赋值给LIU

HELLO

[[email protected] ~]# echo$LIU

HELLO

[[email protected] ~]# echo${DAYI:-HELLO}  #变量DAYI存在,返回DAYI的值

dayi123DAYIdayi

[[email protected] ~]# echo${YI:-HELLO}    #变量YI不存在,所以返回HELLO,但并没有赋值

HELLO

[[email protected] ~]# echo$YI

[[email protected] ~]# echo${DAYI:+HELLO}   #变量DAYI存在,所以返回HELLO

HELLO

[[email protected] ~]# echo${hehe:+HELLO}  #变量hehe不存在,所以返回空

[[email protected] ~]#

4、补充一些小命令

(1)创建临时文件和目录

  用法:mktemp filename.XXXX   创建并系那是临时文件

  选项:-d  创建临时目录

  注:X必须为大写,而且数量不小于三

[[email protected] script]#mktemp /tmp/dayi.XXXX

/tmp/dayi.dA5h

[[email protected] script]#mktemp -d /tmp/dayi123.XXXX

/tmp/dayi123.jkIq

(2)install命令

  作用:复制文件并设置属性

  用法:install [选项] sourcefile  dfile

   选项:-m  指定权限,默认755

       -o   指定属主身份

       -g   指定属组身份

       -d   创建空目录

[[email protected] script]#install -m 755 -o dayi123 -g dayi123 trap.sh trap1.sh [[email protected] script]# lltrap1.sh

-rwxr-xr-x. 1 dayi123dayi123 242 Apr 10 21:29 trap1.sh

5、捕捉信号trap

(1)作用:用于指定在接受到信号后将要采取的动作,常见的用途是在脚本程序被中断时完成清理工作

(2)用法:

    1)trap '触发指令' 信号

    自定义进程收到系统发出的指定信号后,将执行触发指令,而不会执行原操作

    2)trap '' 信号

    忽略信号的操作

    3)trap '-' 信号

    恢复原信号的操作

    4)trap -p

    列出自定义信号操作

(3)案例:

案例1:当按下ctrl+c时终止ping,捕捉信号并进行操作

#!/bin/sh
trap 'echo"stop"' INT
ping 172.16.0.1      

案例2:测试一个网段的主机,当按下ctrl+c时中断测试

#!/bin/sh
trap 'echo"stop";exit 1' INT
for(( i=1;i<=254;i++))
do
    ping 172.16.0.$i
done      

案例三:通过函数实现,测试指定网段的主机是否在线,并为每台主机生成临时文件存储主机状态。测试完成后,删除临时文件。

#!/bin/sh
declare -a hosttmpfiles
trap 'mytrap' INT
 
mytrap(){
    echo "QUIT"
    rm -f ${hosttmpfiles[@]}
    exit 1
}
 
for((i=1;i<=10;i++))
do
    tmpfiles=$(mktemp /tmp/ping.XXXXXX)
    if ping -W 1 -c 1 172.16.0.$i&>/dev/null;then
        echo "172.16.0.$i is up " |tee $tmpfiles
    else
        echo "172.16.0.$i is down" |tee $tmpfiles
    fi
    hosttmpfiles[${#hosttmpfiles[*]}]=$tmpfiles
done
 
mytrap      

6、窗口化编程dialog

(1)作用:提供窗体,但输入完成后,默认将数据输出到错误输出,而不是标准输出(需要安装dialog包)

(2)操作:

   让用户选择:dialog –backtitle“firest test” –-title “create user” –yesno ‘hostname’ 10 30

   让用户输入:dialog –backtitle “firest test” –title “create user” –inputbox‘hostname’ 10 30

   接受用户的选择并赋值给变量:dialog --stdout –backtitle ‘ADD USER’ –title “username” –inputbox “username”10 30

(3)利用窗口化编程创建用户:

#!/bin/sh
while true
do
username=`dialog--stdout --backtitle 'add user' --title 'username' --inputbox "pleaseinput a username:" 20 40`
retval=$?
if [ $retval -ne 0 -o"$username" == "exit" -o -z "$username" ]
then
    exit
elif [ $retval -eq 0 -a-n "$username" ]
   then
      if ! id $username &>/devl/null;
      then
        useradd $username
        pass=`dialog --stdout --backtitle 'adduser' --title 'password' --inputbox "please input password:" 20 40`
        echo $pass | passwd --stdin $username
        dialog --backtitle 'add user' --title'title' --msgbox "add user $username successful" 10 20
     else
        dialog --backtitle 'add user' --title'add user' --msgbox "$username is already create" 10 20
      fi
fi
done      

转载于:https://blog.51cto.com/dayi123/1927621