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

[root@dayi123 ~]#arr1=("dayi123" 13 "string")    #創建一個數組

[root@dayi123 ~]#declare -a arr2     #聲明一個數組

[root@dayi123 ~]#arr2[0]="dayi"     #往數組中添加元素

[root@dayi123 ~]# arr2[1]="18"

(3)獲取數組的長度

    echo ${#array[@]}

    echo ${#array[*]}

[root@dayi123 ~]# echo${#arr1[@]}  #打印數組中元素個數

3

[root@dayi123 ~]# echo${#arr2[*]}   #打印數組中元素個數

1

(4)打印數組的元素

    echo ${array[n]}

    echo ${array[@]}

    echo ${array[*]}

[root@dayi123 ~]# echo${arr1[1]}    #打印數組arr1中的第2個元素

13

[root@dayi123 ~]# echo${arr1[0]}    #打印數組arr1中的第1個元素

dayi123

[root@dayi123 ~]# echo${arr1[@]}   #打印數arr1中的所有元素

dayi123 13 string

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

dayi123 22

(5)數組的賦值

   數組的賦值:array[3]=4

   修改數組元素:arrary[0]=”liuyi”

[root@dayi123 ~]#arr1[3]=4

[root@dayi123 ~]#arr1[0]="liu"

[root@dayi123 ~]# echo${arr1[*]}

liu 13 string 4

(6)數組內容的截取

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

[root@dayi123 ~]# echo${arr1[*]:1:2}

13 string

(7)數組內容的替換

   echo ${arr1[@]/n/m}      #將數組中的第一個n替換爲m

[root@dayi123 ~]# echo${arr1[*]/"liu"/"dayi123"}

dayi123 13 string 4dayi123

(8)數組的刪除與數組中元素的刪除

   unset array   #刪除整個數組

   unset array[n]  #刪除數組中第n個元素,刪除一個元素時只能從頭開始一個一個刪除

[root@dayi123 ~]# unsetarr1[0]  #刪除數組中第一個元素

[root@dayi123 ~]# echo${arr1[*]}

13 4 liu

[root@dayi123 ~]# unsetarr1[2]   #直接刪除數組中第二個元素,刪不掉

[root@dayi123 ~]# echo${arr1[*]}

13 4 liu

[root@dayi123 ~]# unsetarr1[1]   #刪除數組中第一個元素,因爲第0個元素已經刪除

[root@dayi123 ~]# echo${arr1[*]}

4 liu

[root@dayi123 ~]# unsetarr1     #刪除整個數組

[root@dayi123 ~]# echo${arr1[*]}

 

[root@dayi123 ~]#

(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

[root@dayi123 ~]#DAYI="i am dayi123"

[root@dayi123 ~]# echo${#DAYI}

12

[root@dayi123 ~]# echo$DAYI | wc -L

12

(2)截取字符串子串

    echo ${variable:n}        #從第n個字符開始截取

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

    echo $variable | cut –c n-m  #從第n個字符開始截取m個字符

[root@dayi123 ~]# echo${DAYI:2}

am dayi123

[root@dayi123 ~]# echo${DAYI:2:5}

am da

[root@dayi123 ~]# echo$DAYI | cut -c 2-5

 am

(3)替換操作

    echo ${variable/char1/char2}    #將字符串中的char1替換爲char2,只替換第一個

    echo ${variable//char1/char2}   #將變量中的所有字符串char1替換爲char2

[root@dayi123 ~]#DAYI="dayi123DAYIdayi"

[root@dayi123 ~]# echo${DAYI/dayi/liu}     #將第一個dayi替換爲liu

liu123DAYIdayi

[root@dayi123 ~]# echo${DAYI//dayi/liu}    #替換所有的dayiliu

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之間的內容

[root@dayi123 ~]# echo$DAYI

dayi123DAYIdayi

[root@dayi123 ~]# echo${DAYI#dayi}    #刪除第一個匹配到的dayi

123DAYIdayi

[root@dayi123 ~]# echo${DAYI#d*i}    #刪除匹配到的d*i之間的內容

123DAYIdayi

[root@dayi123 ~]# echo${DAYI##d*i}  #刪除匹配到的最長的d*i之間的內容

 

[root@dayi123 ~]# echo${DAYI%d*i}   #刪除從結尾匹配到的d*i之間的內容

dayi123DAYI

[root@dayi123 ~]# echo${DAYI%%d*i}  #刪除從結尾匹配到的最長的d*i的內容

 

[root@dayi123 ~]# echo${DAYI%%dayi}  #刪除從結尾匹配到的dayi

dayi123DAYI

(5)字符的大小寫替換

   echo ${variable^^}     #將變量中的小寫字符替換爲大寫

   echo ${variable,,}       #將變量中的大寫字符替換爲小寫

[root@dayi123 ~]# echo${DAYI^^}   

DAYI123DAYIDAYI

[root@dayi123 ~]# echo${DAYI,,}

dayi123dayidayi

(6)變量的測試

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

   ${variable:=char}  #如果變量名存在且非空,則返回變量值,否則設置variable的值爲char,並返回其值

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

[root@dayi123 ~]# echo${DAYI:=HELLO}   #變量DAYI存在,所以返回變量DAYI的值

dayi123DAYIdayi

[root@dayi123 ~]# echo${LIU:=HELLO}    #變量LIU不存在,所以返回HELLO,並賦值給LIU

HELLO

[root@dayi123 ~]# echo$LIU

HELLO

[root@dayi123 ~]# echo${DAYI:-HELLO}  #變量DAYI存在,返回DAYI的值

dayi123DAYIdayi

[root@dayi123 ~]# echo${YI:-HELLO}    #變量YI不存在,所以返回HELLO,但並沒有賦值

HELLO

[root@dayi123 ~]# echo$YI

 

[root@dayi123 ~]# echo${DAYI:+HELLO}   #變量DAYI存在,所以返回HELLO

HELLO

[root@dayi123 ~]# echo${hehe:+HELLO}  #變量hehe不存在,所以返回空

 

[root@dayi123 ~]#

4、補充一些小命令

(1)創建臨時文件和目錄

  用法:mktemp filename.XXXX   創建並系那是臨時文件

  選項:-d  創建臨時目錄

  注:X必須爲大寫,而且數量不小於三

[root@dayi123 script]#mktemp /tmp/dayi.XXXX

/tmp/dayi.dA5h

[root@dayi123 script]#mktemp -d /tmp/dayi123.XXXX

/tmp/dayi123.jkIq

(2)install命令

  作用:複製文件並設置屬性

  用法:install [選項] sourcefile  dfile

   選項:-m  指定權限,默認755

       -o   指定屬主身份

       -g   指定屬組身份

       -d   創建空目錄

[root@dayi123 script]#install -m 755 -o dayi123 -g dayi123 trap.sh trap1.sh [root@dayi123 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



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章