执行脚本:
第一种:需要执行权限 在子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