bash程式設計之case語句,函式
阿新 • • 發佈:2018-11-23
bash指令碼程式設計:之case語句
條件測試:
0: 成功
1-255: 失敗
命令:
[ expression ]
[[ expression ]]
test expression
exPression:
整數測試:
-gt, -ge, -lt, -le, -eq, -ne
字串:
>, < , >=, <=, ==, !=, =~, -z, -n
檔案:
-e, -f, -d, -b, -c, -h, -S, -s, -a, -p, -r, -w, -x
多分支的if語句:
if boolean_expression1; then
suite1
elif boolean_expression2; then
suite2
...
elif boolean_expressionn; then
suiten
else
else_suite
fi
練習:寫一個指令碼,接受如此格式
script.sh {start|stop|restart|status}
1、如是start,那麼建立/var/lock/subsys/script.sh,顯示啟動成功;
2、如果引數是stop,則刪除/var/lock/subsys/script.sh,顯示停止成功
3、如果restart,則刪除,再建立,顯示成功;
4、如果status, 如果檔案存在,則顯示running,否則,顯示stopped
#!/bin/bash
#
myService=`basename $0`
lockFile="/var/lock/subsys/$myService"
[ $# -lt 1 ] && echo "Usage: $myService {start|stop|restart|status}" && exit 4
if [ "$1" == 'start' ]; then
touch $lockFile
echo "Starting $myService OK"
elif [ "$1" == 'stop' ]; then
rm -f $lockFile
echo "Stopping $myService OK"
elif [ "$1" == 'restart' ]; then
rm -f $lockFile
touch $lockFile
echo "Restarting $myService OK"
elif [ "$1" == 'status' ]; then
if [ -f $lockFile ]; then
echo "$myService is running"
else
echo "$myService is stopped"
fi
else
echo "Usage: $myService {start|stop|restart|status}"
exit 3
fi
case語句的語法格式:
case expression in
pattern1)
suite1
;;
pattern2)
suite2
;;
...
patternn)
suiten
;;
*)
other_suite
;;
esac
上述指令碼的case實現:
#!/bin/bash
#
myService=`basename $0`
lockFile="/var/lock/subsys/$myService"
[ $# -lt 1 ] && echo "Usage: $myService {start|stop|restart|status}" && exit 4
case $1 in
'start')
touch $lockFile
echo "Starting $myService OK"
;;
'stop')
rm -f $lockFile
echo "Stopping $myService OK"
;;
'restart')
rm -f $lockFile
touch $lockFile
echo "Restarting $myService OK"
;;
'status')
if [ -f $lockFile ]; then
echo "$myService is running"
else
echo "$myService is stopped"
fi
;;
*)
echo "Usage: $myService {start|stop|restart|status}"
exit 3
;;
esac
case中各pattern可以使用模式:
a|b: a或者b
*:匹配任意長度的任意字元;
?:匹配任意單個字元;
[-]:範圍匹配
[a-z])
[0-9])
練習:寫一個簡單指令碼
1、提示使用者輸入一個任意字元;
2、能判斷此字元是數字、字母或特殊字元;
#!/bin/bash
#
while true; do
read -p "Enter a char: " char
[[ "$char" == 'quit' ]] && break
case $char in
[a-z])
echo "letter"
;;
[0-9])
echo "digit"
;;
*)
echo "special"
;;
esac
done
練習:寫一個指令碼,能對/etc/目錄進行打包備份,備份位置為/backup/etc-日期.字尾
1、顯示如下選單給使用者:
xz) xz compress
gzip) gzip compress
bip2) bzip2 compress
2、根據使用者指定的壓縮工具使用tar打包壓縮;
3、預設為xz;輸入錯誤則需要使用者重新輸入;
#!/bin/bash
#
[ -d /backup ] || mkdir /backup
cat << EOF
Plz choose a compress tool:
xz) xz compress
gzip) gzip compress
bip2) bzip2 compress
EOF
while true; do
read -p "Your option: " option
option=${option:-xz}
case $option in
xz)
compressTool='J'
suffix='xz'
break ;;
gzip)
compressTool='z'
suffix='gz'
break ;;
bzip2)
compressTool='j'
suffix='bz2'
break ;;
*)
echo "wrong option." ;;
esac
done
tar ${compressTool}cf /backup/etc-`date +%F-%H-%M-%S`.tar.$suffix /etc/*
練習:寫一個指令碼,完成如下功能
說明:此指令碼能夠為指定網絡卡建立別名,指定地址;使用格式:mkethalias.sh -v|--verbose -i|--interface ethX
1|-i選項用於指定網絡卡;
2、如果網絡卡存在:在命令列,請使用者指定一個別名;
3、讓使用者指定IP和掩碼;
4、使用者可以同時使用-v或--verbose選項:如果使用了,則在配置完成後,顯示配置結果;否則,則不予顯示;
#!/bin/bash
#
debug=0
while [ $# -ge 1 ]; do
case $1 in
-i|--interface)
ethcard="$2"
shift 2 ;;
-v|--verbose)
debug=1
shift
;;
*)
echo "Wrong options or arguments."
echo "Usage: `basename $0` [-v|--verbose] -i|--interface Interface"
shift $#
;;
esac
done
# echo "Interface: $ethcard , Verbose Flag: $debug "
! ifconfig $ethcard &> /dev/null && echo "No this interface..." && exit 3
read -p "Enter an alias: " ethAlias
read -p "Enter IP: " ipAddr
read -p "Mask: " netMask
ifconfig $ethAlias $ipAddr netmask $netMask
[ $debug -eq 1 ] && ifconfig $ethAlias
bash指令碼程式設計之函式
模組化程式設計的工具
函式:function,功能元件
可被呼叫:函式有函式名
函數出現的地方,而自動被替換成函式定義的程式碼
函式定義
語法:
FuncName() {
函式體
}
function FuncName {
函式體
}
函式有兩種返回值:
正常返回的資料:
函式中的列印語句,如echo或print
函式中命令的執行結果
執行狀態返回值:
取決於函式中執行的最後一條語句
自定義:return N
函式可以接受引數:
在函式體可以使用類似指令碼呼叫位置引數一樣的引數
$1, $2, ...
$#
$*, [email protected]
#!/bin/bash
#
function ShowUserInfo {
[ $# -lt 1 ] && return 6
grep "^$1\>" /etc/passwd | cut -d: -f3,7
}
function main {
while true; do
read -p "Plz enter a user name: " userName
if [ "$userName" == 'quit' ]; then
echo "Quit"
exit 0
fi
if ! id $userName &> /dev/null; then
echo "No such user, please again."
continue
fi
ShowUserInfo $userName
done
}
main
練習:寫一個指令碼,完成如下功能
1、顯示如下選單
disk) show disk info
mem) show memory info
cpu) show cpuinfo
2、顯示使用者選定的內容;
#!/bin/bash
#
ShowMenu() {
cat << EOF
disk) show disk info
mem) show memory info
cpu) show cpuinfo
EOF
}
main() {
ShowMenu
read -p "Plz choose an option: " option
case $option in
disk)
df -h
;;
mem)
free -m
;;
cpu)
cat /proc/cpuinfo
;;
*)
echo "Wrong option"
esac
}
main
如果在函式中使用變數:變數作用域
在函式中使用了在主程式中宣告的變數,重新賦值會直接修改主程式中的變數;
如果不期望函式與主程式中的變數衝突,函式中使用變數都用local修飾;即使用區域性變數;
在函式中使用了在主程式中沒有宣告的變數,在函式執行結束後即被撤消,無論是否使用local修飾符;
如果想把指令碼的全部位置引數,統統傳遞給指令碼中某函式使用,怎麼辦?
使用$*傳遞
練習:寫一個指令碼,判定172.16.0.0網路內有哪些主機線上,線上的用綠色顯示,不線上的用紅色顯示;要求,程式設計中使用函式;
C類網:ping NetAdd.HostAdd
B類網:ping NetAadd.NetAadd.HostAdd.HostAdd
CnetPing() {
for i in {1..254}; do
ping -c 1 -w 1 $1.$i
}
# CnetPing 192.168.10
BnetPing() {
for j in {0.255}; do
CnetPing $1.$j
done
}
AnetPing() {
for m in {0..255}; do
BnetPing $1.$m
done
}
netType=`echo $1 | cut -d'.' -f1`
if [ $netType -gt 0 -a $netType -le 126 ]; then
AnetPing $1
elif [ $netType -ge 128 -a $netType -le 191 ]; then
BnetPing $1
elif [ $netType -ge 192 -a $netType -le 223 ]; then
CnetPing $1
else
echo "Wrong"
exit 3
fi
練習:寫一個指令碼,完成如下功能(使用函式):
1、提示使用者輸入一個可執行命令;
2、獲取這個命令所依賴的所有庫檔案(使用ldd命令);
3、複製命令至/mnt/sysroot/對應的目錄中
解釋:假設,如果複製的是cat命令,其可執行程式的路徑是/bin/cat,那麼就要將/bin/cat複製到/mnt/sysroot/bin/目錄中,如果複製的是useradd命令,而useradd的可執行檔案路徑為/usr/sbin/useradd,那麼就要將其複製到/mnt/sysroot/usr/sbin/目錄中;
4、複製各庫檔案至/mnt/sysroot/對應的目錄中,其要求命令;
#!/bin/bash
#
target=/mnt/sysroot
clearCmd() {
if which $cmd &> /dev/null; then
cmdPath=`which --skip-alias $cmd`
else
echo "No such command"
return 5
fi
}
cmdCopy() {
cmdDir=`dirname $1`
[ -d ${target}${cmdDir} ] || mkdir -p ${target}${cmdDir}
[ -f ${target}${1} ] || cp $1 ${target}${cmdDir}
}
libCopy() {
for lib in `ldd $1 | grep -o "/[^[:space:]]\{1,\}"`; do
libDir=`dirname $lib`
[ -d ${target}${libDir} ] || mkdir -p ${target}${libDir}
[ -f ${target}${lib} ] || cp $lib ${target}${libDir}
done
}
while true; do
read -p "Enter a command: " cmd
if [ "$cmd" == 'quit' ] ;then
echo "quit"
exit 0
fi
clearCmd $cmd
[ $? -eq 5 ] && continue
cmdCopy $cmdPath
libCopy $cmdPath
done
練習:寫一個指令碼,完成如下功能(使用函式):
1、指令碼使用格式:
mkscript.sh [-D|--description "script description"] [-A|--author "script author"] /path/to/somefile
2、如果檔案事先不存在,則建立;且前幾行內容如下所示:
#!/bin/bash
# Description: script description
# Author: script author
#
3、如果事先存在,但不空,且第一行不是“#!/bin/bash”,則提示錯誤並退出;如果第一行是“#!/bin/bash”,則使用vim開啟指令碼;把游標直接定位至最後一行
4、開啟指令碼後關閉時判斷指令碼是否有語法錯誤
如果有,提示輸入y繼續編輯,輸入n放棄並退出;
如果沒有,則給此檔案以執行許可權;
arguParse() {
}