一、函數(shù)
function 函數(shù)名(){
指令蔗崎。。
return n
}
以上可以簡寫成:
函數(shù)名(){
指令..
return n
}
二扰藕、函數(shù)的執(zhí)行
一:不帶參數(shù)的執(zhí)行
1.function和后面的小括號都不帶嗎缓苛,僅僅時函數(shù)名就可以執(zhí)行
2.函數(shù)的定義必須在執(zhí)行之前定義或加載(即先定義后執(zhí)行)
3.函數(shù)執(zhí)行時,會和腳本公用變量邓深,也可以為函數(shù)設(shè)定局部變量及特殊位置參數(shù)
4.函數(shù)中的return和腳本中的exit功能類似未桥,return用來退出函數(shù),exit是用來退出腳本
5.return的返回值會給調(diào)用函數(shù)的程序芥备,而exit的返回值給執(zhí)行程序的shell
6.如果講函數(shù)獨立與腳本之外冬耿,被腳本加載使用時,需要使用source或者"."來提前加載使用
例如:
. /etc/init.d/functions #加載系統(tǒng)函數(shù)中的命令或者參數(shù)變量萌壳,以供后面的程序使用
7.local定義函數(shù)內(nèi)部的局部變量亦镶,變量在離開函數(shù)后會消失
二:帶參數(shù)的執(zhí)行:
函數(shù)名 參數(shù)1 參數(shù)2
1.shell的位置參數(shù)$1日月、$2、..$# 缤骨、$*山孔、$?及$@都可以作為函數(shù)的參數(shù)使用,此時荷憋,父腳本的參數(shù)臨時被隱藏,而$0仍然時父腳本的名稱
2.當函數(shù)執(zhí)行完成時台颠,原來的命令行腳本的參數(shù)恢復
3.函數(shù)的參數(shù)變量是在函數(shù)體里面定義的
小插曲
1.使用cat命令追加多行,如打印選項菜單
cat <<END
1.FIRST
2.SECOND
3.THIRD
END
2.給輸出的字體加顏色
echo -e 識別轉(zhuǎn)義字符,這里識別字符的特殊含義勒庄,加顏色
#顏色的開始
RED_COLOR='\E[1;31m'
GREEN_COLOR='\E[1;32m'
YELLOW_COLOR='\E[1;33m'
BLUE_COLOR='\E[1;33m'
#顏色的結(jié)束
RES='\E[0m'
echo -e ${RED_COLOR} OLD ${RES} #OLD是紅色
echo -e ${GREEN_COLOR} OLD ${RES} #OLD是綠色
echo -e ${YELLOW_COLOR} OLD ${RES} #OLD是黃色
echo -e ${BLUE_COLOR} OLD ${RES} #OLD是藍色
實戰(zhàn)題目一:
用shell腳本檢查某網(wǎng)站是否存在異常
方式一(普通):
#!/bin/bash
if [ $# -ne 1 ];then
usage $"usage $0 url"
fi
wget --spider -q -o /dev/null --tries=1 -T 5 $1
#--spider用于測試串前,不下載,-q不在命令中顯示 -o 輸入到后面的文件中 实蔽,--tries=number為嘗試次數(shù)和-t一樣 -T超時時間和--timeout一樣 -S顯示響應頭
if [ $? -eq 0 ];then
echo "ok"
else
echo "error"
fi
方式二(函數(shù)封裝):
#!/bin/bash
function Usage(){
echo $"Usage:$0 url"
exit 1
}
function check_url(){
wget --spider -q -o /dev/null -t 1 -T 5 $1
if [ $? -eq 0 ];then
echo "ok"
else
echo "error"
fi
}
function main(){
if [ $# -ne 1 ];then
Usage
else
check_url $1
fi
}
main $* #將腳本傳入的參數(shù)全部都傳到主函數(shù)中
實戰(zhàn)題目二:參數(shù)傳入腳本荡碾、檢查某網(wǎng)站是否存在異常,以更專業(yè)的方式輸出
#!/bin/bash
. /etc/init.d/functions #調(diào)用(加載)系統(tǒng)函數(shù),因為下面要用action函數(shù)
function Usage(){
echo $"usage:$0 url"
exit 1
}
function check_url(){
wget --spider -q -o /dev/null -t 1 -T 5 $1
if [ $? -eq 0 ];then
action "test $1" /bin/true
else
action "test $1" /bin/false
fi
}
function main (){
if [ $# -ne 1 ];then
Usage
else
check_url $1
fi
}
main $*
效果如下:
[root@mycentos shell]# sh 3.sh www.baidu.com
test www.baidu.com [ OK ]
[root@mycentos shell]# sh 3.sh www.baidu.c
test www.baidu.c [FAILED]
實戰(zhàn)題目三:用shell開發(fā)模塊化rsync服務啟動腳本
#!/bin/bash
#chkconfig:2345 21 81
#description
#上面2行是將rsync加入開機自啟動服務
#調(diào)用系統(tǒng)函數(shù)
. /etc/init.d/functions
#輸入錯誤提示
function Usage(){
echo $"usage $0 {start|stop|restart}"
exit 1
}
#啟動服務
function Start(){
rsync --daemon #啟動服務
sleep 2 #啟動服務2秒后再做判斷
if [ $(netstat -pantu | grep rsync | wc -l) -ne 0 ];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 -apntu| grep rsync | wc -l) -eq 0 ];then
action "rsyncd is stopped" /bin/true
else
action "rsyncd is stopped" /bin/false
fi
}
case "$1" in
"start")
Start
;;
"stop")
Stop
;;
"restart")
Stop
sleep 1
Start
;;
*)
Usage
esac
結(jié)果如下:
[root@mycentos init.d]# /etc/init.d/rsyncd start
rsyncd is started [ OK ]
[root@mycentos init.d]# lsof -i:873
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
rsync 1478 root 4u IPv4 13067 0t0 TCP *:rsync (LISTEN)
rsync 1478 root 5u IPv6 13068 0t0 TCP *:rsync (LISTEN)
[root@mycentos init.d]# /etc/init.d/rsyncd stop
rsyncd is stopped [ OK ]
[root@mycentos init.d]# lsof -i:873
[root@mycentos init.d]# /etc/init.d/rsyncd restart
rsyncd is stopped [ OK ]
rsyncd is started [ OK ]
[root@mycentos init.d]# lsof -i:873
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
rsync 2379 root 4u IPv4 19734 0t0 TCP *:rsync (LISTEN)
rsync 2379 root 5u IPv6 19735 0t0 TCP *:rsync (LISTEN)
注:
1.在安裝或者啟動時局装,如果遇到找不到“/etc/rsync.conf”文件時坛吁,要用touch建立一個,實際工作中要寫入東西铐尚,此處為了方便就不寫拨脉,為了啟動rsync服務即可
2.rsync具體的脫離xinetd啟動的方式見"shell基礎(chǔ)二"
3.放在/etc/init.d目錄下就可以用service命令啟動,啟動前需要是腳本有執(zhí)行權(quán)限宣增,否則無法執(zhí)行玫膀,也無法自動補全。
4.要加入開機自啟動爹脾,則需要加如腳本中解釋器下面2行帖旨,然后“chkconfig --add rsyncd”加入自啟動 "rsyncd"是/etc/init.d目錄下的服務名稱
實戰(zhàn)四:執(zhí)行shell腳本,打印如下菜單灵妨,柑橘選擇解阅,給選擇的水果加一種顏色。
1.紅色的蘋果
2.綠色的蘋果
3.黃色的蘋果
4.藍色的蘋果
方法一(普通版)
#!/bin/sh
#定義好顏色泌霍,方便后面使用
RED_COLOR='\E[1;31m'
GREEN_COLOR='\E[1;32m'
YELLOW_COLOR='\E[1;33m'
BLUE_COLOR='\E[1;34m'
RES='\E[0m'
cat <<END
====================
1.紅色的蘋果
2.綠色的蘋果
3.黃色的蘋果
4.藍色的蘋果
====================
END
read -p "input a munber you want:" NUM
case "$NUM" in
1)
echo -e ${RED_COLOR}apple${RES}
;;
2)
echo -e ${GREEN_COLOR}apple${RES}
;;
3)
echo -e ${YELLOW_COLOR}apple${RES}
;;
4)
echo -e ${BLUE_COLOR}apple${RES}
;;
*)
echo "usage:input {1|2|3|4}"
exit 1
esac
方法二(函數(shù)封裝):
#!/bin/sh
#定義好顏色货抄,方便后面使用
RED_COLOR='\E[1;31m'
GREEN_COLOR='\E[1;32m'
YELLOW_COLOR='\E[1;33m'
BLUE_COLOR='\E[1;34m'
RES='\E[0m'
function Menu(){
cat <<END
====================
1.紅色的蘋果
2.綠色的蘋果
3.黃色的蘋果
4.藍色的蘋果
====================
END
}
function Usage(){
echo "$usage:input a number{1|2|3|4}"
exit 1
}
function Choose(){
read -p "input a munber you want:" NUM
case "$NUM" in
1)
echo -e ${RED_COLOR}apple${RES}
;;
2)
echo -e ${GREEN_COLOR}apple${RES}
;;
3)
echo -e ${YELLOW_COLOR}apple${RES}
;;
4)
echo -e ${BLUE_COLOR}apple${RES}
;;
*)
Usage
esac
}
function Main(){
Menu
Choose
}
Main
效果如圖:
實戰(zhàn)五:緊接著上題,請開發(fā)一個給制定內(nèi)容加上制定顏色的腳本
#!/bin/bash
RED_COLOR='\E[1;31m'
GREEN_COLOR='\E[1;32m'
YELLOW_COLOR='\E[1;33m'
BLUE_COLOR='\E[1;34m'
RES='\E[0m'
function Usage(){
echo $"usage:$0 txt {red|green|yellow|pink}"
exit 1
}
if [ $# -ne 2 ];then
Usage
exit
fi
function Choose(){
case "$2" in
"red")
echo -e ${RED_COLOR}$1${RES}
;;
"green")
echo -e ${GREEN_COLOR}$1${RES}
;;
"yellow")
echo -e ${YELLOW_COLOR}$1${RES}
;;
"blue")
echo -e ${BLUE_COLOR}$1${RES}
;;
*)
Usage
esac
}
function Main(){
Choose $1 $2
}
Main $*
注:
1.將參數(shù)二的顏色付給參數(shù)一
2.精確匹配單詞的三種方式
1.grep -w 'oldboy' file
2.grep "\boldboy\b" file
3.grep "^oldboy$" file
以上都是將出現(xiàn)oldboy單詞的行顯示出來烹吵,而不是將包含oldboy的行顯示出來
實戰(zhàn)五:
啟動Nginx服務的命令:/application/nginx/sbin/nginx
關(guān)閉Nginx服務的命令:/application/nginx/sbin/nginx -s stop
請開發(fā)腳本碉熄,以實現(xiàn)Nginx服務啟動和關(guān)閉功能,具體腳本命令為/etc/init.d/nginxd {start|stop|restart},并通過chkconfig進行開機自啟動
思路:
1.判斷開啟或關(guān)閉服務(一是檢測pid文件是否存在肋拔,存在就是開啟锈津,不存在就是服務已經(jīng)關(guān)閉),或者使用netstat鏈接數(shù)也可以
2.start和stop分別構(gòu)成函數(shù)
3.對函數(shù)和命令運行的返回值進行處理
4.chkconfig實現(xiàn)服務自啟動
代碼:
#!/bin/sh
#chkconfig:2345 27 83
#description
source /etc/init.d/functions #加載系統(tǒng)函數(shù)庫
#定義文件路徑
PATH="/application/nginx/sbin"
PID_PATH="/application/nginx/logs/nginx.pid"
REVEAL=0
function Usage(){
echo $"usage:$0 {start|stop|restart}"
exit 1
}
#判斷參數(shù)的個數(shù)
if [ $# -ne 1 ];then
Usage
fi
#開始函數(shù)
function Start(){
if [ ! -f $PID_PATH ];then #若原來服務是關(guān)閉的
$PATH/nginx #開啟服務
REVEAL=$?
if [ $REVEAL -eq 0 ];then #判斷是否開啟
action "nginx is started" /bin/true
else
action "nginx is started" /bin/false
fi
else
echo "nginx is running"
fi
return $REVEAL
}
function Stop(){#結(jié)束函數(shù)
if [ -f $PID_PATH ];then #若原來服務是啟動的
$PATH/nginx -s stop #關(guān)閉服務
REVEAL=$?
if [ $REVEAL -eq 0 ];then #判斷是否關(guān)閉
action "nginx is stopped" /bin/true
else
action "nginx is stopped" /bin/false
fi
return $REVEAL
else
echo "nginx is no running"
fi
return $REVEAL
}
case "$1" in
"start")
Start
REVEAL=$?
;;
"stop")
Stop
REVEAL=$?
;;
"restart")
Stop
Start
REVEAL=$?
;;
*)
Usage
esac
exit $REVEAL
效果如下:
[root@mycentos init.d]# /etc/init.d/nginxd start
nginx is running
[root@mycentos init.d]# /etc/init.d/nginxd stop
nginx is stopped [ OK ]
[root@mycentos init.d]# /etc/init.d/nginxd start
nginx is started [ OK ]
[root@mycentos init.d]# lsof -i:80
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
nginx 2928 root 6u IPv4 23795 0t0 TCP *:http (LISTEN)
nginx 2929 nginx 6u IPv4 23795 0t0 TCP *:http (LISTEN)
[root@mycentos init.d]# /etc/init.d/nginxd restart
nginx is stopped [ OK ]
nginx is started [ OK ]
[root@mycentos init.d]# lsof -i:80
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
nginx 2940 root 6u IPv4 24824 0t0 TCP *:http (LISTEN)
nginx 2941 nginx 6u IPv4 24824 0t0 TCP *:http (LISTEN)
彩蛋一枚
return :
1.用來退出函數(shù)凉蜂,后面的函數(shù)里面的內(nèi)容不再執(zhí)行
exit:
2.用來退出腳本琼梆,后面的內(nèi)容不再執(zhí)行
function test(){
return 1
}
test #函數(shù)執(zhí)行完成后性誉,$?會得到test中return后面的返回值
ls -l ./ #這條命令執(zhí)行成功,$?變成0
function test2(){
exit 99
}
test2 #函數(shù)執(zhí)行完成后茎杂,$?變成99,也就是exit后面的數(shù)值
$?的值會不斷的改變错览,有別于其他語言的函數(shù)調(diào)用的返回值。
結(jié)果:
#!/bin/bash
function test(){
return 8
}
echo $? #0
test
echo $? #8
function test2(){
return 9
}
echo $? #0
test2
echo $? #9
ls -l ./
echo $? #0
exit 10
此shell執(zhí)行結(jié)束后煌往,echo $? 結(jié)果是10