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
发布了89 篇原创文章 · 获赞 196 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/qq_40791253/article/details/104618411