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