執行腳本:
第一種:需要執行權限 在子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