Shell之進階篇(判斷語句)


進階篇(一)

執行腳本:
第一種:需要執行權限 在子shell中執行

# ./filename.sh

第二種:不需要執行權限 在當前shell中執行
提示: 通常修改系統配置文件中如 /etc/profile 的PATH等變量後,使之在當前shell中生效

# bash filename.sh
# . filename.sh
# source filename.sh

調試腳本:
第一種:僅調試 syntax error(僅調試語法錯誤)

# sh -n filename.sh

第二種:以調試的方式執行,查詢整個執行過程

# sh -vx filename.sh

一、if 條件判斷

單分支結構

if 條件測試
then 命令序列
fi
if 條件測試;then 命令序列
fi

雙分支結構

if 條件測試
then 命令序列
else 命令序列
fi

多分支結構

if 條件測試1
then 命令序列

[elif 條件測試2
then 命令序列

elif 條件測試3
then 命令序列]

else 命令序列
fi

文件測試  [ 操作符 文件或目錄 ]
[] = test 命令
注:使用 [] 時,需要前後加上空格。
test命令參數,可以參考菜鳥:

https://www.runoob.com/linux/linux-shell-test.html

[root@zh-docker ~]# test -d /root
[root@zh-docker ~]# echo $?      
0
[root@zh-docker ~]# test -d /root/ip.txt 
[root@zh-docker ~]# echo $?
1
[root@zh-docker ~]# test -f /root/ip.txt  
[root@zh-docker ~]# echo $?              
0
[root@zh-docker ~]# test -f /root
[root@zh-docker ~]# echo $?      
1
[root@zh-docker ~]# [ -d /root ]    
[root@zh-docker ~]# echo $?
0
[root@zh-docker ~]# [ -d /root/ip.txt ]
[root@zh-docker ~]# echo $?
1
參數 說明
[ -e dir|file ] 判斷文件或目錄是否存在
[ -d dir ] 判斷是否爲目錄
[ -f file ] 判斷是否爲文件
[ -r file ] 判斷該文件是否可讀
[ -x file ] 判斷該文件是否可執行
[ -w file ] 判斷該文件是否可寫
[ -L file ] 判斷文件是否一個符號鏈接(同-h)
# 根下不存在 zcoder 目錄創建 zcoder 目錄
[ ! -d /zcoder ] && mkdir /zcoder
[ -d /zcoder ] || mkdir /zcoder

&& 兩邊爲真時,才爲真
|| 一邊爲真即爲真

數值比較  [ 數據1 操作符 數據2 ]

操作符 說明
-gt 大於
-lt 小於
-eq 等於
-ne 不等於
-ge 大於等於
-le 小於等於

小 實 驗一:

每隔1分鐘查詢一次系統磁盤容量,若磁盤容量超過10%便發送警告郵件至服務器。
(1分鐘與10%只是爲了達到實驗效果)
每隔1分鐘查詢一次系統運行內存,若系統運行內存超過40%便發送警告郵件至服務器。
(1分鐘與40%同樣也只是爲了達到實驗效果)

實現代碼:

#!/bin/bash
#########################################
#2020-03-02                             #
#System disk/memory capacity monitoring # 
#Author Zcoder                          #
#########################################
#Memory variable
mem_total=`free -m| grep "Mem"| awk '{print $2}'`
mem_used=`free -m| grep "Mem"| awk '{print $3}'`
mem_percent=$((mem_used*100/mem_total))

#Disk variable
disk_used=`df -Th| grep "/$"| awk '{print $(NF-1)}'| awk -F"%" '{print $1}'`

#mail variable
mail_user="zcoder"
check_mailpack=`rpm -qa *mail*| grep -c "mail"`

#Install mail server
if [ $check_mailpack -lt 2 ]; then
        yum insatll -y mailx sendmail
fi

#Send disk mail
if [ $disk_used -ge 10 ]; then
        echo  "`date +%F-%H` disk: ${disk_used}% is used" |mail -s "Disk is fully!!!" $mail_user
fi

#Send memory mail
if [ $mem_percent -ge 40 ]; then
        echo "`date +%F-%H` Memory: ${mem_percent}% is used" |mail -s "Memory is fully!!!" $mail_user
fi

代碼測試:

#將磁盤監控加入定時任務,每隔一分鐘執行一次
[root@zh-docker scripts]# crontab -l
*/1 * * * * /bin/bash /root/scripts/disk_monitoring.sh

C語言風格的數值比較  ((數據1 操作符 數據2))
操作符直接用符合表示即可

> ; < ; == ; >= ; <= ; != 
[root@zh-docker scripts]# (($(id -u)==0)) && echo "super user"
super user

字符串比較
提示:字符串在進行比較時需套上 雙引號

參數 說明
= 等於則爲真
== 等於則爲真
!= 不相等則爲真
-z 字符串的長度爲零則爲真
-n 字符串的長度不爲零則爲真
[root@zh-docker scripts]# a=""
[root@zh-docker scripts]# echo ${#a}
0
[root@zh-docker scripts]# [ -z "$a" ]
[root@zh-docker scripts]# echo $?
0
[root@zh-docker scripts]# [ -n "$a" ]
[root@zh-docker scripts]# echo $?
1

[[ 變量名 =~ 正則表達式 ]]  正則匹配

[root@zh-docker scripts]# user="root"
[root@zh-docker scripts]# [[ "$user"=~^r ]]
[root@zh-docker scripts]# echo $?
0

小 實 驗二:

  交互式,用戶確認是否安裝KVM。
注:其實這個實驗有很多瑕疵(比如:當用戶輸入yes時,怎麼判斷),但現在只是爲了運用一些if判斷,後面將會用case判斷進行完善。

#!/usr/bin/bash
read -p "please input y if you want to install KVM: " KVM_install
if [ ! $KVM_install = "y" ]; then
        echo "input error"
        exit 2
fi

二、case 判斷語句

case 語法結構

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

小 實 驗一:

  是否確定關閉服務器防火牆與Selinux,[y/n]:
  要求:能夠判斷用戶輸入的yes與no

read -p "Whether to turn off the firewall and selinux,input [yes/no]: " turn
case "$turn" in
Y|YES|Yes|y|yes|yES|YEs|yEs|YeS)
	systemctl stop firewalld.service;systemctl disable firewalld.service
	setenforce 0;sed -ri '/^SELINUX/c\SELINUX=disabled' config
	echo -e '\033[32;40;1mTurn off the firewall and selinux successful!\033[0m'
	;;
N|NO|No|n|no|nO)
	echo -e '\033[31;40;1mNothing to do!\033[0m'
	;;
"")
	echo -e '\033[31;40;1mTyping error, please try again!\033[0m'
	;;
*)
	echo -e '\033[31;40;1mTyping error, please try again!\033[0m'
	;;
esac

  很明顯,使用case語句有個優點便是它可以同時判斷多個值,當用戶輸入不同的值來表示yes時,if語句卻只能判斷一個。

小 實 驗二:

  爲某企業的堡壘機寫一個開機自動執行登錄其他服務器的腳本,用戶無需輸入服務器ip,登錄密碼等,直接通過選項便可登錄其他服務器。

堡壘機(又稱爲:跳板機、jumpserver)

生產環境:

  • 業務服務器不允許直接連接,應通過堡壘機進行連接;
  • 業務服務器不允許root用戶直接登錄

所有主機準備遠程管理用戶:zcoder
物理機可以使用 zcoder 用戶 登錄 OtherServer
1)密碼認證
2)密鑰認證 zcoder:ssh-keygen ssh-copy-id Server1
在這裏插入圖片描述
實現代碼:

#!/bin/bash
##########################
#2020-03-09              #
#Author Zcoder           #
##########################
#Can`t Ctrl+C  (Cannot be terminated)
trap "" HUP INT OUIT TSTP

#Server Variable
Server1=192.168.56.102
Server2=192.168.56.103
SQLDB=192.168.56.104
clear

while :
do
	cat <<-EOF
	+---------------------------------------+
	|			1. Server1                  |
	|			2. Server2                  |
	|			3 SQLDB                     |
	+---------------------------------------+		
	EOF

	echo -en "\e[1;32mplease input number to into server: \e[0m"
	read number
	case $number in
		1)
			ssh zcoder@$Server1
			;;
		2)
			ssh zcoder@$Server2
			;;
		3)
			ssh zcoder@$SQLDB
			;;
		"")
			;;
		*)
			echo "Input error!"
			;;
	esac
done

將腳本加入bash_profile,系統啓動時,自動執行此腳本

echo "/root/scripts/jumpserver.sh" >> /root/.bash_profile
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章