[RHEL]-10-shell脚本

引言

Linux下的shell脚本,就像是windows下的Batch批处理,能够熟练的使用sh脚本可以极大的提高工作效率。

文章目录

0×1.条件判断式

在阅读本文前,请大家先参考一下[[ubuntu入门手册]-16-Shell脚本基础]这篇文章中的内容,本文不会对shell脚本的基础语法做过多的解释。

下面首先来看看Shell脚本中的条件判断式的工作方式:

条件判断式被包含在一对中括号中,若条件成立则返回数字0,否则便返回其他数值(条件不成立时,大多数情况下返回1);

条件判断语句可判断文件、逻辑、整数值、字符串等,文件判断有如下常用参数:

-d 判断是否为目录;
-e 判断文件或目录是否存在;
-f 判断是否为文件;
-r 判断当前用户对文件是否有读取权限;
-w 判断当前用户对文件是否有写入权限;
-x 判断当前用户对文件是否有执行权限;

下面来看几个简单实例:

					#在终端所在目录有两个文件和一个文件夹,权限如下所示
					[qing@qingsword.com ~]$ ls -ld file_a file_b dir_a/
					drwxrwxr-x. 2 qing qing 6 Nov 17 03:58 dir_a/
					-rw-rw-r--. 1 qing qing 0 Nov 17 03:58 file_a
					----------. 1 qing qing 0 Nov 17 03:58 file_b

					#判断file_a是否为文件,"$?"可以打印出上一条命令的返回结果,如果条件成立"$?"的值就会是0,如果条件不成立就会是非0的其他值
					[qing@qingsword.com ~]$ [ -f file_a ]
					[qing@qingsword.com ~]$ echo $?
					0

					#判断file_a是否为目录
					[qing@qingsword.com ~]$ [ -d file_a ]
					[qing@qingsword.com ~]$ echo $?
					1

					#判断file_a是否存在(file_a可以是目录或文件)
					[qing@qingsword.com ~]$ [ -e file_a ]
					[qing@qingsword.com ~]$ echo $?
					0

					[qing@qingsword.com ~]$ [ -d dir_a ]
					[qing@qingsword.com ~]$ echo $?
					0

					#判断当前用户对file_b是否有可写权限
					[qing@qingsword.com ~]$ [ -w file_b ]
					[qing@qingsword.com ~]$ echo $?
					1
					

条件判断中添加逻辑运算符:

					#逻辑"或"运算符运用到条件判断中,和如何语言所用的逻辑相同,如果file_a存在,那么将运行&&后面的部分,如果不存在,则不会执行echo
					[qing@qingsword.com ~]$ [ -e file_a ] && echo "目标存在" 
					目标存在

					#逻辑"与"运算符,如果前面的表达式为假,则执行echo
					[qing@qingsword.com ~]$ [ -e file_c ] || echo "目标不存在" 
					目标不存在

					#将两者结合使用
					[qing@qingsword.com ~]$ [ -e file_c ] && echo "目标存在" || echo "目标不存 在"
					目标不存在

					#如果用户不为root,打印hello user,否则打印出hello root,$USER变量保存了当前登录终端的用户名(等号和不等号可用于字符串的比对)
					[qing@qingsword.com ~]$ [ $USER != root ] && echo "hello user" || echo "hello root"
					hello user
					

除了=和!=可用于判断字符串是否相等外,还有一个比较常用的参数-z,可用于判断字符串是否为空,例如:

					[qing@qingsword.com ~]$ str1=""
					[qing@qingsword.com ~]$ str2="www.qingsword.com"
					[qing@qingsword.com ~]$ [ -z $str1 ] && echo "空字符串" || echo "非空字符串"
					空字符串
					[qing@qingsword.com ~]$ [ -z $str2 ] && echo "空字符串" || echo "非空字符串"
					非空字符串
					

在进行整数大小比对时,推荐使用参数操作符,下面是一些常用的参数操作符:

-eq 判断是否等于;
-ne 判断是否不等于;
-gt 判断是否大于;
-lt 判断是否小于;
-le 判断是否等于或小于;
-ge 判断是否大于或等于;

下面举几个简单实例:

					#判断1是否等于2
					[qing@qingsword.com ~]$ [ 1 -eq 2 ] && echo "True" || echo "False"
					False

					#判断1是否等于1
					[qing@qingsword.com ~]$ [ 1 -eq 1 ] && echo "True" || echo "False"
					True

					#判断1是否不等于2
					[qing@qingsword.com ~]$ [ 1 -ne 2 ] && echo "True" || echo "False"
					True

					#判断1是否小于等于2
					[qing@qingsword.com ~]$ [ 1 -le 2 ] && echo "True" || echo "False"
					True
					

下面是整数判断式在实际环境中的应用,判断系统可用内存是否低于某个值:

					#首先将free命令的执行结果保存到FreeMEM变量中(一旦保存,这个值就不会变化了,在实际环境中,可以每间隔多少秒执行一次下面的语句,然后判断内存是否低于一个指定的值),下面这条命令,首先用grep筛选出了free命令中的Mem行,再使用awk命令取出这一行中的第四列
					[qing@qingsword.com ~]$ FreeMEM=$(free -m | grep Mem: |awk '{print $4}')

					[qing@qingsword.com ~]$ echo $FreeMEM
					149

					#然后使用我们上面的整数判断式去判断这个值是否低于500
					[qing@qingsword.com ~]$ [ $FreeMEM -le 500 ] && echo "可用内存低于500M" || echo "可用内存高于500M"
					可用内存低于500M
					

0×2.shell脚本实例

实例一:局域网存活主机探测

					#用vim创建example_1.sh脚本,输入下面的内容
					[qing@qingsword.com ~]$ vim example_1.sh
					#!/bin/bash
					IPADDR_subnet="192.168.1."
					#从100循环到110
					for ((i=100;i<=110;i=i+1))
					do 
					 #将两个字符串连接起来,得到IP地址
					 IPADDR=${IPADDR_subnet}${i}
					 #使用ping命令探测每一个主机,ping2次,数据包发送间隔0.2秒,等待超时时间为1秒(大写W),将输出重定向到null文件
					 ping -c 2 -i 0.2 -W 1 $IPADDR &> /dev/null
					 #通过$?判断上一条命令是否成功执行
					 if [ $? -eq 0 ] ; then
					  echo "Host $IPADDR is On-line"
					 else
					  echo "Host $IPADDR is Off-line"
					 fi
					done

					#执行结果如下
					[qing@qingsword.com ~]$ bash example_1.sh 
					Host 192.168.1.100 is Off-line
					Host 192.168.1.101 is On-line
					Host 192.168.1.102 is Off-line
					Host 192.168.1.103 is Off-line
					Host 192.168.1.104 is On-line
					Host 192.168.1.105 is On-line
					Host 192.168.1.106 is Off-line
					Host 192.168.1.107 is Off-line
					Host 192.168.1.108 is Off-line
					Host 192.168.1.109 is Off-line
					Host 192.168.1.110 is Off-line
					

Ps:能够ping通只能说明对方主机应答ICMP数据包,一些防火墙屏蔽了ICMP的主机,就算主机是开机状态,但也可能ping不通。

实例二:实现批量创建用户

					#方法一:
					[qing@qingsword.com ~]$ vim example_2.sh
					#!/bin/bash
					u="User_"
					#提示用户输出一个密码作为这些用户的密码
					read -p "Enter the users password:" PASSWD
					#循环创建4个用户
					for ((i=1;i<=4;i=i+1))
					do
					 #用户名为User_1~4
					 USER=${u}${i}

					 #如果用户存在
					 id $USER &> /dev/null
					 if [ $? -eq 0 ] ; then
					  echo "$USER already exists"
					 else
					  #如果用户不存在,创建并设置密码
					  useradd $USER
					  echo $PASSWD | passwd --stdin $USER &> /dev/null
					  if [ $? -eq 0 ] ; then
					   echo "$USER Create Success."
					  else
					   echo "$USER Create Failure."
					  fi
					 fi
					done

					#方法二:
					#先创建一个user.txt文件保存需要创建的用户的用户名
					[qing@qingsword.com ~]$ echo "qing_1" >> user.txt
					[qing@qingsword.com ~]$ echo "qing_2" >> user.txt
					[qing@qingsword.com ~]$ echo "qing_3" >> user.txt

					#使用脚本文件逐行读取上面这个user.txt文件
					[qing@qingsword.com ~]$ vim example_3.sh
					#!/bin/bash
					read -p "Enter the users password:" PASSWD

					#使用for循环,逐行读取cat user.txt执行结果集中的用户名(`cat user.txt`为$(cat user.txt))
					for USER in `cat user.txt`
					do
					 id $USER &> /dev/null
					 if [ $? -eq 0 ] ; then
					  echo "$USER already exists"
					 else
					  useradd $USER &> /dev/null
					  echo "$PASSWD" | passwd --stdin $USER &> /dev/null
					  if [ $? -eq 0 ] ; then
					   echo "$USER Create Success."
					  else
					   echo "$USER Create Failure."
					  fi
					 fi
					done
					

实例三:猜数字

					[qing@qingsword.com ~]$ vim example_4.sh
					#!/bin/bash
					#计数器
					COUNT=0
					#初始化一个0~999之间的整数,expr计算命令会计算后面表达式的值,$RANDOM是一个系统随机值变量,范围为0~32767,用这个随机值除以1000取余,就能得到0~999之间的随机整数
					N=$(expr $RANDOM % 1000)
					echo "猜数字游戏,请输入一个0~999之间的整数"
					while true
					 do
					  read -p "你猜:" NUM
					  #计数器加1
					  let COUNT++ 
					  if [ $NUM -lt $N ] ; then
					   echo "小了"
					  elif [ $NUM -gt $N ] ; then
					   echo "大了"
					  elif [ $NUM -eq $N ] ; then
					   echo "恭喜,猜对了!"
					   echo "一共猜了$COUNT次"
					   exit 0
					  fi
					 done
					

实例四:判断用户输入是字母、数字还是特殊字符

					[qing@qingsword.com ~]$ vim example_5.sh
					#!/bin/bash
					read -p "请输入一个字符:" CHAR
					case $CHAR in
					[a-z]|[A-Z])
					 echo "大小写字母" ;;
					[0-9])
					 echo "数字" ;;
					*)
					 echo "特殊字符"
					esac

					#程序输出
					[qing@qingsword.com ~]$ bash example_5.sh 
					请输入一个字符:1
					数字
					[qing@qingsword.com ~]$ bash example_5.sh 
					请输入一个字符:a
					大小写字母
					[qing@qingsword.com ~]$ bash example_5.sh 
					请输入一个字符:G
					大小写字母
					[qing@qingsword.com ~]$ bash example_5.sh 
					请输入一个字符:*
					特殊字符