天天看點

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