《Shell 程式設計》06_if 條件語句
阿新 • • 發佈:2018-11-01
《Shell 程式設計》06_if 條件語句
標籤(空格分隔): Shell
文章目錄
6.1 if 條件語句的語法
6.1.1. 單分支結構
第一種:
if <條件表示式>
then
指令
fi
第二種:
if <條件表示式>; then
指令
fi
條件語句巢狀:
if <條件表示式>
then
if <條件表示式>
then
指令
fi
fi
- “<條件表示式>” 可以是 test、[]、[[]]、(()),也可以是命令;
- 分號相當於命令換行。
6.1.2. 雙分支結構
if <條件表示式>
then
指令集1
else
指令集2
fi
6.1.3 多分支結構
if <條件表示式>; then
指令1
elif <條件表示式2>; then
指令2
else
指令3
fi
- 每個 elif 都要帶有 then;
- 最後結尾的 else 後面沒有 then。
6.2 if 條件語句多種條件表示式語法
(1)test 條件表示式
if test 表示式; then
指令
fi
(2)[] 條件表示式
if [ 字串或算數表示式 ]; then 指令 fi
(3)[[]] 條件表示式
if [[ 字串表示式 ]]; then
指令
fi
(4)(()) 條件表示式
if ((算術表示式)); then
指令
fi
(5) 命令表示式
if 命令; then
指令
fi
例 6-1
開發 Shell 指令碼判斷系統剩餘記憶體的大小,如果低於 100 MB,就郵件報警給系統管理員,並且將指令碼加入定時任務,即每 3 分鐘檢查一次。
1)獲取系統當前剩餘記憶體的值
[[email protected] ~]# free -m
total used free shared buff/cache available
Mem: 1823 154 1071 34 596 1451
Swap: 1023 0 1023
[[email protected] ~]# free -m|awk 'NR==3 {print $NF}'
1023
2)配置郵件報警
[[email protected] ~]# echo -e "set [email protected] smtp=smtp.163.com nset smtp-auth-user=yanglt7 smtp-auth-password=授權碼 smtp-auth=login" >>/etc/mail.rc
[[email protected] ~]# tail -1 /etc/mail.rc
set [email protected] smtp=smtp.163.com nset smtp-auth-user=yanglt7 smtp-auth-password=授權碼 smtp-auth=login
[[email protected] ~]# echo "ylt"|mail -s "title" [email protected]
#<==測試郵件傳送
[[email protected] ~]# echo "mail test" >/tmp/test.txt
#<==將正文放入檔案
[[email protected] ~]# mail -s "title" [email protected] </tmp/test.txt
#<==讀取檔案內容併發送郵件
3)編寫 Shell 指令碼
#!/bin/bash
FreeMem=`free -m|awk 'NR==3 {print $NF}'`
CHARS="Current memory is $FreeMem."
if [ $FreeMem -lt 100 ]; then
echo $CHARS|tee /tmp/messages.txt #<==螢幕輸出提示,並寫入檔案。
mail -s "`date + $F-$T`$CHARS [email protected]" </tmp/memssages.txt
fi
#<[email protected] 是接收報警郵件的郵箱,[email protected] 是傳送報警郵件的郵箱。
4)將上述指令碼加入crond 定時任務中,每 3 分鐘檢查一次,達到閥值就發郵件報警
[[email protected] ~]# crontab -l|tail -2
# monitor sys mem at 20181024 by ylt
*/3 * * * * /bin/sh /home/ylt/scripts/mailMem.sh &>/dev/null
例 6-2
使用 if 語句和 read 讀入實現整數大小的比較。
#!/bin/bash
read -t 10 -p "pls input two num:" a b
[ -z $a ] || [ -z $b ] &&{
echo "pls input two num again."
exit 1
}
expr $a + 1 &>/dev/null
RETVAL1=$?
expr $b + 1 &>/dev/null
RETVAL2=$?
[[ $RETVAL1 -eq 0 -a $RETVAL2 -eq 0 ]] ||{
echo "pls input two 'num'."
exit 3
}
if [ $a -gt $b ]; then
echo "$a > $b"
elif [$a -lt $b ]; then
echo "$a < $b"
else
echo "$a=$b"
exit 0
6.3 監控 Web 和資料庫
例 6-3
用 if 條件語句針對 Nginx Web 服務或 MySQL 資料庫服務是否正常進行檢測,如果服務未啟動,則啟動相應的服務。
1)監控 Web 服務和 MySQL 資料庫服務是否異常的常見方法:
- 埠監控
- 在伺服器本地監控服務埠的常見命令有 netstat、ss、lsof
- 從遠端監控伺服器本地埠的命令有 telnet、nmap、nc
- 監控服務程序或程序數
- 此方法適合本地伺服器,過濾的是程序的名字。命令為:
- ps -ef|grep nginx|wc-l
- ps -ef|grep mysql|wc-l
- 此方法適合本地伺服器,過濾的是程序的名字。命令為:
- 在客戶端模擬使用者訪問
- 使用 wget 或 curl 命令進行測試(如果監控資料庫,則需要轉為通過 Web 伺服器去訪問資料庫),並對測試結果做三種判斷:
- 利用返回值(echo $?)
- 獲取特殊字串(需事先開發程式)
- 根據 HTTP 響應 header 的情況
- 使用 wget 或 curl 命令進行測試(如果監控資料庫,則需要轉為通過 Web 伺服器去訪問資料庫),並對測試結果做三種判斷:
- 登入 MySQL 資料庫判斷
- 通過 MySQL 客戶端連線資料庫,根據返回值或返回內容判斷。例如:mysql -uroot -pylt -e “select version();” &>/dev/null; echo $?
2)監控 mysql 資料庫異常
埠監控:
[[email protected] scripts]# /etc/init.d/mysqld start
Starting MySQL.. SUCCESS!
[[email protected] scripts]# netstat -lntup|grep 3306|wc -l
1
[[email protected] scripts]# netstat -lntup|grep mysql|wc -l
1
[[email protected] scripts]# ss -lntup|grep mysql|wc -l
1
[[email protected] scripts]# ss -lntup|grep 3306|wc -l
1
[[email protected] scripts]# lsof -i tcp:3306|wc -l
2
遠端監控伺服器監控本地埠:
[[email protected] scripts]# nmap 127.0.0.1 -p 3306|grep open|wc -l
1
[[email protected] scripts]# echo -e "\n"|telnet 127.0.0.1 3306 2>/dev/null|grep Connected|wc -l
1
[[email protected] scripts]# nc -w 2 127.0.0.1 3306 &>/dev/null
伺服器程序或程序數進行監控(適合本地伺服器):
[[email protected] scripts]# ps -ef|grep mysql|grep -v grep|wc -l
2
3)開發監控 MySQL 資料庫的指令碼
#!/bin/bash
#if [ `netstat -lnt|grep 3306|awk -F "[ :]+" '{print $5}'` -eq 3306 ]; then
#if [ "`netstat -lnt|grep 3306|awk -F "[ :]+" '{print $5}'`" = "3306" ]; then
#if [ `netstat -lntup|grep mysqld|wc -l` -gt 0 ]; then
#if [ `lsof -i tcp:3306|wc-l` -gt 0 ]; then
if [ `ps -ef|grep -v grep|grep mysql|wc -l` -gt 0 ]; then
echo "MySQL is Running."
else
echo "MySQL is Stopped."
/etc/init.d/mysqld start
fi
4)監控 Nginx Web 服務異常
埠監控:
[[email protected] ~]# /application/nginx/sbin/nginx
[[email protected] ~]# netstat -lntup|grep nginx|wc -l
1
[[email protected] ~]# netstat -lntup|grep 80|wc -l
1
[[email protected] ~]# ss -lntup|grep -w 80|wc -l
1
[[email protected] ~]# lsof -i tcp:80|wc -l
3
伺服器程序或程序數進行監控(適合本地伺服器):
[[email protected] scripts]# ps -ef|grep nginx|grep -v grep|wc -l
2
5)開發監控 Nginx 的指令碼
#!/bin/bash
#if [ `netstat -lntup|grep nginx|wc -l` -gt 0 ]; then
#if [ `netstat -lntup|grep -w 80|wc -l` -eq 80 ]; then
if [ `lsof -i tcp:80|wc -l` -gt 0 ]; then
if [ `ps -ef|grep -v grep|grep nginx|wc -l` -ge 1 ]
echo "Nginx is Running."
else
echo "Nginx is Stopped."
/application/nginx/sbin/nginx
fi
6.4 判斷字串是否為數字
1)使用 sed 加正則表示式
#<==刪除一個字串中的所有數字,看字串的長度是否為0,如果不為0,則說明不是整數。
[[email protected] ~]# [ -n "`echo ylt123|sed 's/[0-9]//g'`" ] && echo char || echo int
char
[[email protected] ~]# [ -n "`echo 123|sed 's/[0-9]//g'`" ] && echo char || echo int
int
[[email protected] ~]# [ -z "`echo ylt123|sed 's/[0-9]//g'`" ] && echo int || echo char
char
[[email protected] ~]# [ -z "`echo 123|sed 's/[0-9]//g'`" ] && echo int || echo char
int
2)變數的子串替換加正則表示式
#<==如果 num 長度不為0,並且把 num 中的非數字部分刪除,然後再看結果是不是等於 num 本身,如果兩者成立,則 num 就是數字。
[[email protected] ~]# num=222
[[email protected] ~]# [ -n "$num" -a "$num" = "${num//[^0-9]/}" ] && echo "it is num."
it is num.
3)通過 expr 判斷
[[email protected] ~]# expr ylt + 1 &>/dev/null
[[email protected] ~]# echo $?
2
[[email protected] ~]# expr 123 + 1 &>/dev/null
[[email protected] ~]# echo $?
0
4)利用 “=~” 符號判斷
[[email protected] ~]# [[ ylt123 =~ ^[0-9]+$ ]] && echo int || echo char
char
[[email protected] ~]# [[ 123 =~ ^[0-9]+$ ]] && echo int || echo char
int
6.5 判斷字串長度是否為 0
1)使用字串條件表示式 -z 和 -n
[[email protected] ~]# [ -z "ylt" ] && echo 1 || echo 0
0
[[email protected] ~]# [ -n "ylt" ] && echo 1 || echo 0
1
2)使用變數子串判斷
[[email protected] ~]# char=ylt
[[email protected] ~]# [ ${#char} -eq 0 ] && echo 1 || echo 0
0
3)使用 ecpr length 函式判斷
[[email protected] ~]# [ `expr length "ylt"` -eq 0 ] && echo 1 || echo 0
0
4)使用 wc 的 -L 引數統計判斷
[[email protected] ~]# [ `echo ylt|wc -L` -eq 0 ] && echo 1 || echo 0
0
5)使用 awk lenghth 函式判斷
[[email protected] ~]# [ `echo ylt|awk '{print length}'` -eq 0 ] && echo 1 || echo 0
0
6.6 開發 rsync 服務的啟動指令碼
#!/bin/bash
if [ $# -ne 1 ]; then
echo $"USAGE:$0 {start|stop|restart}"
exit 1
fi
if [ "$1" = "start" ]; then
echo "rsyncd is starting..."
rsync --daemon
sleep 2
if [ `netstat -lntup|grep 873|wc -l` -ge 1 ]; then
echo "rsyndc is started."
exit 0
fi
elif [ "$1" = "stop" ]; then
echo "rsyncd is stopping..."
pkill rsync
sleep 1
if [ `netstat -lntup|grep 873|wc -l` -eq 0 ]; then
echo "rsyncd is stopped."
exit 0
fi
elif [ "$1" = "restart" ]; then
echo "rsyncd is stopping..."
pkill rsync
sleep 1
killpro=`netstat -lntup|grep 873|wc -l`
rsync --daemon
echo "rsyncd is starting..."
sleep 1
startpro=`netstat -lntup|grep 873|wc -l`
if [ $killpro -eq 0 -a $startpro -ge 1 ]; then
echo "rsyncd is restarted."
exit 0
fi
else
echo $"USAGE:$0 {start|stop|restart}"
exit 2
fi