#前言:今天我們來聊聊shell腳本中的函數知識,看一下函數的優勢,執行過程和相關的使用案例,我們也來看一下shell和python的函數書寫方式有什麼不同
#簡介
1、函數也具有別名類似的功能 2、函數是把程序裏多次調用相同的代碼部分定義成一份,然後給這份代碼定義個名字,如果出現重複的就調用就行了
#函數的優勢
1、把相同的程序段定義成函數,可以減少整個程序的代碼量 2、可以讓程序代碼結構更清晰 3、增加程序的可讀、易讀性、以及管理性 4、可以實現程序功能模塊化,不同的程序使用函數模塊化
#語法格式
函數名(){ 指令 return n } 規範寫法 function 函數名(){ 指令 return n } #提示:shell的返回值是exit輸出返回值,函數裏用return輸出返回值
#函數的執行
調用函數
#1、直接執行函數名即可(不帶括號)
#注意
執行函數時,函數後的小括號不要帶了
函數定義及函數整體必須在要執行的函數名的前面定義
#2、帶參數的函數執行方法
函數名 參數1 參數2
#提示:函數的傳參和腳本的傳參類似
#shell的位置參數($1 $2 $3 $4 $5 $# $* $? $@)都可以時函數的參數
#$0比較特殊,仍然是父腳本的名稱
#在shell函數裏面,return命令功能與shell裏的exit類似,作用時跳出函數
#在shell函數裏面使用exit會退出整個shell腳本,而不是退出shell函數
#return語句會返回一個退出值(返回值)給調用函數的程序
#我們來看一下python的函數書寫方式
#提示:def是define的意思,定義
最基本的語法: def 函數名(): 函數體 函數名() #調用函數 帶有參數的語法 def 函數名(形參列表): 函數體(代碼塊,return) 函數名(實參列表) :調用
#看一下執行過程
# def wan(): #定義函數 # print("今天一起去玩") # print("去哪裏玩呢") # print("我不知道") # wan() #調用函數 '''講解執行的過程 1.定義函數wan() 2.調用函數wan() 3.準備開始執行函數 4.打印,今天一起去玩 5.打印,去哪裏完 6.打印,我不知道 7.函數執行完畢,本次調用完畢,wan()函數調用完畢 '''
#使用
#例1:沒有去調用函數
[root@shell scripts]# pwd /scripts [root@shell scripts]# cat hs01.sh #!/bin/bash guoke(){ echo "I am guoke" } [root@shell scripts]# sh hs01.sh [root@shell scripts]# #如果沒有去調用函數的話,那麼就沒有輸出
#例2:調用函數
[root@shell scripts]# cat hs01.sh #!/bin/bash guoke(){ echo "I am guoke" } guoke #調用函數 [root@shell scripts]# sh hs01.sh I am guoke
#例3:多次調用
[root@shell scripts]# cat hs01.sh #!/bin/bash guoke(){ echo "I am guoke" } guoke guoke guoke [root@shell scripts]# sh hs01.sh I am guoke I am guoke I am guoke
#例4:將函數寫到/etc/init.d/functions裏面,然後通過其他腳本進行調用
#/etc/init.d/functions boy(){ echo "I am guoke-boy" } return 0 #提示:不要放在return 0後面,要不然就是退出了,沒有調用 [root@shell scripts]# cat hs01.sh #通過腳本去調用boy函數 #!/bin/bash . /etc/init.d/functions #引入系統函數庫 guoke(){ echo "I am guoke" } guoke boy #調用/etc/init.d/functions中的函數
[root@shell scripts]# sh hs01.sh #執行之後打印 I am guoke I am guoke-boy
#例5:將函數寫到/etc/init.d/functions裏面,通過其他腳本進行調用然後傳參
#/etc/init.d/functions boy(){ echo "I am $1" } #提示:$1:腳本的傳入的第一個參數 [root@shell scripts]# cat hs01.sh #通過腳本去調用boy函數 #!/bin/bash . /etc/init.d/functions #引入系統函數庫 guoke(){ echo "I am guoke" } guoke boy guoke-boy #調用/etc/init.d/functions中的函數,後面接着傳參 [root@shell scripts]# sh hs01.sh #執行之後打印 I am guoke I am guoke-boy
#例6:設置提示函數,如果傳的參數的值不符合就打印幫助函數
[root@shell scripts]# cat hs02.sh #!/bin/bash usage(){ echo "Usage: $0 key beginservernum endservernum example: $0 ff 1 2" } [[ $# != 3 ]] && usage && exit 1 #如果傳入的參數不等於3的話,就調用後面的函數,並退出腳本 [[ -z $1 || -z $2 || -z $3 ]] && usage && exit 1 #如果傳入的$1,$2,$3三個參數的值爲空,那麼就調用後面的函數,並退出腳本
[root@shell scripts]# sh hs02.sh 22 33 #當傳入的參數不等於3個的時候就執行usage函數,並退出腳本 Usage: hs02.sh key beginservernum endservernum example: hs02.sh ff 1 2
#例7:將函數的傳參轉換成腳本文件命令行傳參,判斷任意指定的URL是否存在異常
[root@shell scripts]# cat hs03.sh #!/bin/bash . /etc/init.d/functions function usage(){ echo $"usage:$0 url" exit 1 } function check_url(){ wget --spider -q -o /dev/null --tries=1 -T 5 $1 if [ $? -eq 0 ];then action "$1 is success." /bin/true else action "$1 is failure." /bin/false fi } function main(){ if [ $# -ne 1 ];then usage fi check_url $1 } main $*
#參數解釋
. /etc/init.d/functions #引入系統函數庫 function usage(){ #幫助函數 function check_url(){ #檢測URL函數 wget --spider -q -o /dev/null --tries=1 -T 5 $1 #--spider:判斷網址是否有效,-q:不顯示執行過程,-o:將軟件輸出信息保存到軟件,-T:指定超時時間 action "$1 is success." /bin/true #action:調用系統函數庫的用法 function main(){ #主函數 if [ $# -ne 1 ];then #判斷:如果傳參的參數不等1個,那麼久打印幫助函數,提示用戶 check_url $1 #接收函數的傳輸
main $* #$*:把命令行接收的所有參數作爲函數參數傳給函數內部
#測試
[root@shell scripts]# sh hs03.sh #如果沒有加參數,就調用提示函數 usage:hs03.sh url [root@shell scripts]# sh hs03.sh www.guokeboy.com #輸入錯誤地址 www.guokeboy.com is failure. [FAILED](失敗) [root@shell scripts]# sh hs03.sh www.baidu.com #輸入正確地址 www.baidu.com is success. [ OK ]
#例8:給任意字符串加指定顏色
[root@shell scripts]# cat hs04.sh #!/bin/bash RED_COLOR='\E[1;31m' GREEN_COLOR='\E[1;32m' YELLOW_COLOR='\E[1;33m' BLUE_COLOR='\E[1;34m' PINK='\E[1;35m' RES='\E[0m' usage(){ if [ $# -ne 2 ];then echo "USAGE:$0 {red|green|yellow|blue|pink}" contents exit 1 fi } color(){ case "$1" in red) echo -e "${RED_COLOR} $2 ${RES}" ;; green) echo -e "${GREEN_COLOR} $2 ${RES}" ;; yellow) echo -e "${YELLOW_COLOR} $2 ${RES}" ;; blue) echo -e "${BLUE_COLOR} $2 ${RES}" ;; *) usage esac } main(){ if [ $# -ne 2 ];then usage fi color $1 $2 } main $*
#參數解釋
#1.定義顏色變量 數字對應的顏色:30(黑色)、31(紅色)、32(綠色)、33(黃色)、34(藍色、35(粉紅)、36(青色)、37(白色) #2.定義幫助函數 #3.定義顏色函數,使用case來獲取輸入的值 #4.主函數,判斷輸入的參數是否爲2個,如果不是就調用幫助函數
#測試
#如果執行腳本,不加參數的話就打印幫助函數
#例9:使用shell函數開發rsync服務啓動腳本
#使用start、stop、restart函數將代碼 模塊化,使用系統函數action優化顯示
[root@shell init.d]# cat rsyncd #!/bin/bash #chkconfig: 2345 20 80 #description: Rsyncd start scripts by guoke. . /etc/init.d/functions function usage(){ echo $"usage:$0 {start|stop|restart}" exit 1 } function start(){ rsync --daemon sleep 1 if [ `netstat -unplt | grep rsync | wc -l` -ge 1 ];then action "rsyncd is started." /bin/true else action "rsyncd is started." /bin/false fi } function stop(){ killall rsync &>/dev/null sleep 2 if [ `netstat -unptl | grep rsync |wc -l` -eq 0 ];then action "rsyncd is stopped." /bin/true else action "rsyncd is stopped." /bin/false fi } function restart(){ stop sleep 2 start } function main(){ if [ $# -ne 1 ];then usage fi case "$1" in start) start ;; stop) stop ;; restart) stop sleep 1 start ;; *) usage esac } main $*
#參數解釋:引入系統函數庫,定義幫助函數,然後定義start函數,stop函數,restart函數,定義主函數,主函數裏面首先使用if判斷傳入的參數是不是爲一個,如果不是就調用幫助函數,然後使用case語句獲取傳入的參數,再調用相關的函數,$*:把命令行接收的所有參數作爲函數參數傳給函數內部
#測試
[root@shell init.d]# sh rsyncd stop rsyncd is stopped. [ OK ] [root@shell init.d]# sh rsyncd start rsyncd is started. [ OK ] [root@shell init.d]# sh rsyncd restart rsyncd is stopped. [ OK ] rsyncd is started. [ OK ]
#總結:將腳本中功能進行模塊化之後,就會使腳本比較易讀和清晰,提升管理效率。好了,這次就分享到這了,寫的不好地方還望指出,多多交流提高,下次再會。。。