1. 程式人生 > 其它 >Linux shell 知識心得03 流程控制if判斷+case語句

Linux shell 知識心得03 流程控制if判斷+case語句

流程控制之if判斷

一:單分支if

語法

if 條件;then
    要執行的命令1
 	要執行的命令2
    要執行的命令3
    ...
fi

# 上述語法可以用一行程式碼代替
[ 條件資訊 ] && xxx

示例

[root@simon test]# cat disk_monitor.sh 
#!/usr/bin/env bash

disk_use=$(df -P |grep '/$' |awk '{print $5}' |awk -F% '{print $1}')
if [ $disk_use -gt 10 ];then
    echo "warning:Not enough hard disk space"
fi
[root@simon test]# . disk_monitor.sh 
warning:Not enough hard disk space

注意:if 測試中還可以執行命令 根據命令的返回值做判斷

[root@simon ~]# if cd / ;then echo Y ;fi
Y
[root@simon /]# if grep -q root /etc/passwd ;then echo Y ;fi
Y

二:雙分支if

語法

if 條件;then
    要執行的命令1
 	要執行的命令2
    要執行的命令3
    ...
else
    要執行的命令1
 	要執行的命令2
    要執行的命令3
    ...
fi

# 上述語法可以用一行程式碼代替
[ 條件資訊 ] && xxx || xxxx

示例

#!/bin/bash
username='simon'
password='123'
read -p 'user: ' name 
read -p 'passwd: ' passwd

if [ $name = $username -a $passwd = $password ];then
    echo 'login successful'
else
    echo 'username or password err'
fi

三:多分支if

語法:

if 條件;then
    要執行的命令1
 	要執行的命令2
    要執行的命令3
    ...
elif 條件;then
    要執行的命令1
 	要執行的命令2
    要執行的命令3
    ...
elif 條件;then
    要執行的命令1
 	要執行的命令2
    要執行的命令3
    ...
...
else
    要執行的命令1
 	要執行的命令2
    要執行的命令3
    ...
fi

示例1:猜年齡

======================版本1======================
#!/bin/bash
age=87
read -p 'num: ' n

if [ $n -eq $age ];then
    echo 'you get it'
elif [ $n -gt $age ];then
    echo 'too big'
elif [ $n -lt $age ];then
    echo 'too small'
fi

======================版本2======================
#!/bin/bash

read -p ">>> " num

[[ ! $num =~ ^[0-9]+$ ]] && echo "請輸入數字" && exit

if [ $num -gt 18 ];then
    echo "too big"
elif [ $num -lt 18 ];then
    echo "too small"
else
    echo "you got it"
fi

示例2:查詢成績

======================版本1======================
#!/bin/bash
read -p 'your score: ' score

if [ $score -ge 90  ];then
    echo '優秀'
elif [ $score -ge 70 -a $score -lt 90 ];then
    echo '良好'
elif [ $score -ge 60 -a $score -lt 70 ];then
    echo '一般'
elif [ $score -lt 60 ];then
    echo '較差'
fi

======================版本2======================
#!/bin/bash

read -p "your score>>> " score

[[ ! $score =~ ^[0-9]+$ ]] && echo "請輸入數字" && exit

if [ $score -ge 90 ];then
    echo "優秀"
elif [ $score -ge 70 ];then
    echo "良好"
elif [ $score -ge 60 ];then
    echo "一般"
else
    echo "較差"
fi

示例3:判斷是否是數字

read -p "請輸入一個數值: " numwhile :do        if [[ $num =~ ^[0-9]+$ ]];then                break        else                read -p "不是數字,請重新輸入數值: " num        fidoneecho "你輸入的數字是: $num"

四 練習

1、編寫指令碼,命令列傳入一個檔案路徑,判斷檔案的型別

[root@localhost ~]# cat test_file.sh #!/bin/bashif [ -d $1 ]    then        echo "$1 is directory"elif [ -b $1 ]    then        echo "$1 is block"elif [ -f $1 ]    then        echo "$1 is regular file"else        echo 'unknown'fi[root@localhost ~]# ./test_file.sh /etc/passwd/etc/passwd is regular file

2、檢測指定的主機是否可以ping通,必須使用$1變數

[root@simon test]# cat ping.sh #!/bin/bashping -c2 $1 &>/dev/nullif [ $? -eq 0 ];then    echo "ok"else    echo "down"fi[root@simon test]# chmod +x ping.sh [root@simon test]# ./ping.sh 10.10.0.1down[root@simon test]# 

3、判斷一個使用者是否存在

[root@simon test]# cat check_user.sh #!/bin/bashid $1 &> /dev/nullif [ $? -eq 0 ];then    echo "user $1 exists"else    echo "user $1 not exists"fi[root@simon test]# chmod +x check_user.sh [root@simon test]# ./check_user.sh simonuser simon exists[root@simon test]# ./check_user.sh xxuser xx not exists

4、檢測httpd軟體是否安裝,沒有的話則安裝

[root@simon test]# cat check_httpd.sh#!/bin/bashrpm -q httpd &>/dev/nullif [ $? -eq 0 ];then    echo "已經安裝"else    echo "正在安裝..."    yum install httpd -y &>/dev/nullfi

5、判斷80埠的狀態,未開啟則重啟

[root@simon test]# cat check_port.sh #!/bin/bashnetstat -an |grep LISTEN |grep '\b80\b' &>/dev/nullif [ $? -eq 0 ];then    echo "80埠ok"else     echo "80埠down"    echo "正在重啟..."    systemctl restart httpd &> /dev/null    if [ $? -eq 0 ];then        echo "重啟成功"    else        echo "重啟失敗"    fifi

6、編寫監控指令碼,如果
根分割槽剩餘空間小於10%
記憶體的可用空間小於30%
向用戶simon傳送告警郵件,郵件的內容包含使用率相關資訊

答案

[root@simon test]# cat monitor.sh #!/bin/bash#! /bin/bash# 提取根分割槽剩餘空間use_disk=`df / | grep / | awk '{print $5}'`use_percent=`echo $use_disk|cut -d% -f1`# 提取記憶體剩餘空間avail_mem=`free | awk 'NR==2{print $NF}'`total_mem=`free | awk 'NR==2{print $2}'`avail_percent=`echo "scale=2;$avail_mem/$total_mem"|bc | cut -d. -f2`# 注意 磁碟提取的數值單位為 kb、 記憶體提取的單位為 Mbif [ $use_percent -gt 90 ];then     echo "郵件內容:根分割槽已經使用為${user_disk}低於10%,請及時處理!!!" | mail -s "硬碟報警郵件" rootfiif [ $avail_percent -lt 30 ];then     echo "郵件內容:記憶體剩餘${free_percent}%,低於30%" | mail -s "記憶體報警郵件" [email protected]

測試:

# 檢視163郵箱# [root@simon test]# cat /var/spool/mail/root 

mailx配置

[root@simon ~]# yum install mailx -y[root@simon ~]# cat /etc/mail.rcset [email protected] set smtp=smtps://smtp.qq.com:465set [email protected] smtp-auth-password="xxxxxxxxxx"set smtp-auth=loginset ssl-verify=ignoreset nss-config-dir=/etc/pki/nssdb/

解釋

set from:設定發件人set smtp:設定外部STMP伺服器set smtp-auth-user:設定STMP使用者名稱(一般為完整郵箱地址)set smtp-auth-password:設定SMTP密碼,需要登入[email protected]在設定->賬戶->開啟POP3/SMTP服務->獲取密碼

測試

[root@simon ~]# echo "臥槽" | mail -s "報警郵件" [email protected][root@simon ~]# Error in certificate: Peer's certificate issuer has been marked as not trusted by the.

上述報錯的解決方式為,依次執行下述命令

mkdir -p /root/.certs/echo -n | openssl s_client -connect smtp.qq.com:465 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > ~/.certs/qq.crtcertutil -A -n "GeoTrust SSL CA" -t "C,," -d ~/.certs -i ~/.certs/qq.crtcertutil -A -n "GeoTrust Global CA" -t "C,," -d ~/.certs -i ~/.certs/qq.crtcertutil -L -d /root/.certscd /root/.certscertutil -A -n "GeoTrust SSL CA - G3" -t "Pu,Pu,Pu" -d ./ -i qq.crt# 最後出現這句就可以了Notice: Trust flag u is set automatically if the private key is present.# 重新修改配置檔案的最後一行[root@simon ~]# cat /etc/mail.rcset [email protected] set smtp=smtps://smtp.qq.com:465set [email protected] smtp-auth-password="xxxxxxxxxx"set smtp-auth=loginset ssl-verify=ignore# set nss-config-dir=/etc/pki/nssdb/  # 改為下面一行set nss-config-dir=/root/.certs# 然後重新測試郵件傳送即可

7、根據作業系統不同進行yum源優化 centos6 centos7 centos8

[root@simon shell]# cat check_yum.sh #!/bin/bashmv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup &>/dev/nullvar=$(awk '{print $(NF-1)}' /etc/redhat-release)os_version=`echo ${var%%.*}`if [ $os_version -eq 7 ];then    wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo &>/dev/nullelif [ $os_version -eq 6 ];then    wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-6.repo &>/dev/nullelif [ $os_version -eq 5 ];then    wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-5.repo &>/dev/nullelse    echo "請檢查確認系統版本資訊"fi

流程控制之case語句

一 語法

case 變數 in
模式1)
	命令序列1
	;;
模式2)
	命令序列2
	;;
模式3)
	命令序列3
	;;
*)
	無匹配後命令序列
esac

二 案例

案例1

#!/bin/bash
read -p "username: " -t 5 username
echo
if [ -z $username ];then
    username="default"
fi

case $username in
root)
    echo "管理員使用者"
    ;;
simon)
    echo "普通使用者"
    ;;
default)
    echo "預設使用者"
    ;;
*)
    echo "其他使用者"
esac

案例2:編寫nginx啟動指令碼

[root@simon shell]# cat nginx_stat.sh 
#!/bin/bash

. /etc/init.d/functions
if [ $# -ne 1 ]
   then
      echo "USAGE $0 {start|stop|restart}"
      exit 1
fi


if [ "$1" == "start" ]
   then 
      action "start nginx" /bin/true
elif [ "$1" == "stop" ]
   then
      action "stop nginx" /bin/true
elif [ "$1" == "restart" ]
   then
      action "restart nginx" /bin/true
else
      echo "USAGE $0 {start|stop|restart}"
      exit 1
fi
    
[root@simon shell]# chmod +x nginx_stat.sh 
[root@simon shell]# ./nginx_stat.sh start
start nginx                                                [  確定  ]
[root@simon shell]# ./nginx_stat.sh restart
restart nginx                                              [  確定  ]
[root@simon shell]# ./nginx_stat.sh 
USAGE ./nginx_stat.sh {start|stop|restart}

案例3:編寫nginx啟動指令碼

# 儲備知識1
netstat -lntup|grep  ":80\b"  # \b錨定單詞的結尾

# 儲備知識2
action:列印一段資訊並執行給定的命令,然後根據給定命令的執行的結果來呼叫 success,failure方法,確定最終顯示的內容
 
[root@simon shell]# action "nginx start is" :
nginx start is                                             [  確定  ]
[root@simon shell]# action "nginx start is" /bin/true
nginx start is                                             [  確定  ]
[root@simon shell]# action "nginx start is" /bin/false
nginx start is                                             [失敗]


# 程式碼
[root@simon shell]# cat nginx_stat.sh 
#!/bin/bash

. /etc/init.d/functions
args=$1

fun(){
    [ $? -eq 0 ] && action "Nginx $args is " /bin/true  || echo "Nginx $args is " /bin/false 
}

case $1 in
   start)
       netstat -an | grep -i Listen | grep -q "\b80\b"
       if [ $? -eq 0 ]
       then 
          echo "Nginx is runing..."
       else
           /usr/sbin/nginx
           fun
       fi
       ;;
   stop)
       /usr/sbin/nginx -s stop
       fun
       ;;
   reload)
       /usr/sbin/nginx -s reload
       fun
       ;;
  restart)
       netstat -lntup|grep  ":80\b" &>/dev/null
       if [ $? -ne 0 ]
       then
          /usr/sbin/nginx
          [ $? -eq 0 ] && echo "Nginx start is ok" || echo "Nginx start is failed"
       else
          /usr/sbin/nginx -s stop                             
          [ $? -eq 0 ] && echo "Nginx stop is ok" || echo "Nginx stop is failed"
          sleep 2
          /usr/sbin/nginx 
          fun 
       fi
       ;;
   status)
       netstat -lntup|grep  ":80\b" &>/dev/null
       if [ $? -eq 0 ]
       then
          echo "Nginx is runing ..."
       else
          echo "Nginx is not runing ..."
       fi
       ;;
    *)
        echo "Usage: $0 {start|stop|status|restart|reload}"
        exit 2
esac

案例4:編寫一個簡易跳板機指令碼

# 儲備知識
Linux中斷訊號區別為:鍵入不同、對應操作不同、啟用不同。

1、HUP中斷訊號:HUP中斷訊號的對應操作為讓程序掛起,睡眠。同<Ctrl+X>

2、INT中斷訊號:INT中斷訊號的對應操作為正常關閉所有程序。同<Ctrl+C>

3、TERM中斷訊號 15:TERM中斷訊號的對應操作為正常的退出程序。

4、KILL中斷訊號 9:KILL中斷訊號的對應操作為強制關閉程序。

5、STOP 19暫停(同 Ctrl + Z)

6、CONT 18繼續(與STOP相反, fg/bg命令)

7、TSTP中斷訊號:TSTP中斷訊號的對應操作為暫時停用程序。


# 程式碼
[root@simon shell]# cat jumpserver.sh 
#!/bin/bash
    
cat<<EOF
1. BACKUP 10.0.0.41
2. WEB02  192.168.12.21
3. WEB03  10.0.0.9
EOF
trap "echo 不要亂按鍵盤,否則伺服器將會爆炸" HUP INT TSTP

while true
do
    read -p "請輸入連線主機編號資訊: " num
    read -p "請輸入賬號: " user
    # read -p "請輸入要執行的命令: " cmd
    case $num in
       1)
           ssh [email protected]
           [ $? -ne 0 ] && echo "connect faild"
           ;;
       2)
           ssh [email protected]
           [ $? -ne 0 ] && echo "connect faild"
           ;;
       *)
           echo "請輸入連線主機資訊"
    esac
done