Linux基础-shell脚本知识整理和脚本编写----------变量、运算符、流程控制、函数、计划任务(发送邮件)
I:知识整理:变量、运算符、流程控制、函数、计划任务
变量
系统变量:set:显示所有变量
env:环境变量
常用系统变量:
path pwd lang home histsize ps1 ifs
变量赋值:x=test
echo $x
删除变量 unset x
自定义变量
定义变量: 变量名=变量值 变量名必须以字母或下划线开头,区分大小写 ip1=192.168.2.115
引用变量: $变量名 或 ${变量名}
查看变量: echo $变量名 set(所有变量:包括自定义变量和环境变量)
取消变量: unset 变量名
作用范围: 仅在当前shell中有效
环境变量
定义环境变量: 方法一 export back_dir2=/home/backup
方法二 export back_dir1 将自定义变量转换成环境变量
引用环境变量: $变量名 或 ${变量名}
查看环境变量: echo $变量名 env 例如env |grep back_dir2
取消环境变量: unset 变量名
变量作用范围: 在当前shell和子shell有效
位置变量
$1 $2 $3 $4 $5 $6 $7 $8 $9 ${10}
预定义变量
$0 脚本名
$* 所有的参数
$@ 所有的参数
$# 参数的个数
$$ 当前进程的PID
$! 上一个进程的PID
$? 上一个命令的返回值
运算符
+ 加 - 减 * 乘 / 除 % 取余 < 小于 >大于 <= 小于等于 >=大于等于 == 判断 !=非 && 且 ||或 = += *= /= %=
测试文件状态
-d 目录 -s 文件长度 > 0、非空 -f 正规文件 -w 可写 -r 可读 -x 可执行 -L 符号连接 -u 文件有 suid 位设置
测试数值
[ 10000 -gt 250 ] #不要使用大于号小于号等于号等,要使用man test中规定的:
-eq 等于 -ne 不等于 -gt 大于 -lt 小于 -ge 大于等于 -le 小于等于
流程控制:
if
if 结构语句 单分支结构 if 条件测试 then 命令序列 fi
双分支结构 if 条件测试 then 命令序列 else 命令序列 fi
多分支结构 if 条件测试1 then 命令序列
[elif 条件测试2 then 命令序列 elif 条件测试3 then 命令序列]...
else 命令序列 fi
示例:超市卖水果 [root@test day1]# vim supermarket.sh #!/bin/bash read -p "输入您要查询的商品: " var if [ $var = 'apple' ] then echo "apple is 10/kg" elif [ $var = 'banana' ] then echo "banana is 20/kg" elif [ $var = 'orange' ] then echo "orange is 30/kg" else echo "你要的水果我们不卖" fi
while
while 条件测试
do
循环体
done
==当条件测试成立(条件测试为真),执行循环体
示例:输入用户名和密码,正确后输入命令
bogon:~ centos$ cat a.sh #!/bin/sh while : do read -p "please input your name: " name read -p "please input your password: " pwd if [ -z $name ] || [ -z $pwd ] then continue fi if [ $name = "alex" -a $pwd = "alex123" ] then echo "login successful" while : do read -p "please input your cmd: " cmd if [ "$cmd" = "quit" ] then break fi $cmd done else echo "login error" fi done echo "--------"
for
for 循环
for 变量名 [ in 取值列表 ]
do
循环体
done
示例:猜数字游戏
[root@test day2]# vim guest.sh #!/bin/bash num=$(($RANDOM%5+1)) for i in {1..5} do read -p "输入您要猜的数值(1~100): " var if [ $var -eq $num ] then echo "you are win" elif [ $var -gt $num ] then echo "you are big" else echo "you are small" fi done
函数
完成特定功能的代码片段(块)
在shell中定义函数可以使用代码模块化,便于复用代码
函数必须先定义才可以使用
一、定义函数
方法一:
函数名() {
函数要实现的功能代码
}
方法二:
function 函数名 {
函数要实现的功能代码
}
二、调用函数
函数名
函数名 参数1 参数2
内置函数
gsub(r,s) # 在整个$0中用s替代r 相当于 sed 's///g' gsub(r,s,t) # 在整个t中用s替代r index(s,t) # 返回s中字符串t的第一位置 length(s) # 返回s长度 match(s,r) # 测试s是否包含匹配r的字符串 split(s,a,fs) # 在fs上将s分成序列a sprint(fmt,exp) # 返回经fmt格式化后的exp sub(r,s) # 用$0中最左边最长的子串代替s 相当于 sed 's///' substr(s,p) # 返回字符串s中从p开始的后缀部分 substr(s,p,n) # 返回字符串s中从p开始长度为n的后缀部分
计划任务crontab
什么是计划任务:
后台运行,到了预定的时间就会自动执行的任务,前提是:事先手动将计划任务设定好。这就用到了crond服务
crond服务相关的软件包
[root@MiWiFi-R3-srv ~]# rpm -qa |grep cron
cronie-anacron-1.4.11-14.el7.x86_64
crontabs-1.11-6.20121102git.el7.noarch
cronie-1.4.11-14.el7.x86_64
这些包在最小化安装系统时就已经安装了,并且会开机自启动crond服务,并为我们提供好编写计划任务的crontab命令。
计划任务分为两类:系统级和用户级
首先需要知道的是,无论是系统级还是用户级的cron计划都是文本文件,系 统的计划文件存放在/etc/crontab路径下。用户的计划文件放在/var/spool/cron/用户名,不管是哪一种,都可以满足我们定制计划任务的需求。
root用户可以直接对文件进行修改来编写计划任务也可以使用 crontab -e命令,而普通用户只能使用后者。除此之外,系统crontab文件中任务的定义也有所不同,在前五个部分之后插入了一个“用户”部分。
crontab命令编写计划任务
语 法:crontab [-u <用户名称>][配置文件] 或 crontab [-u <用户名称>][-elr]
crontab任务配置基本格式:
* * * * * command
分钟(0-59) 小时(0-23) 日期(1-31) 月份(1-12) 星期(0-6,0代表星期天) 命令
第1列表示分钟1~59 每分钟用*或者 */1表示
第2列表示小时1~23(0表示0点)
第3列表示日期1~31
第4列表示月份1~12
第5列标识号星期0~6(0表示星期天)
第6列要运行的命令
参数:
-e 编辑该用户的计时器设置。
-l 列出该用户的计时器设置。
-r 删除该用户的计时器设置。
-u<用户名称> 指定要设定计时器的用户名称。
crontab例子 30 21 * * * /usr/local/etc/rc.d/apache restart #每晚的21:30 重启apache 45 4 1,10,22 * * /usr/local/etc/rc.d/apache restart #每月1、10、22日的4 : 45重启apache
Ⅱ:作业:开发脚本自动部署及监控(shell脚本编写)
1.编写脚本自动部署反向代理、web、nfs;
要求:
1)部署nginx反向代理三个web服务,调度算法使用加权轮询;
2)所有web服务使用共享存储nfs,保证所有web都对其有读写权限,保证数据一致性;
proxy 192.168.11.62 #nginx代理,nfs服务端 web01 192.168. 11.74 #web01,nfs客户端 web02 192.168.11.75 #web02,nfs客户端 #poxy上安装nginx代理,nfs客户端,脚本如下 [root@proxy mnt]# cat install_nginx.sh #!/bin/bash #insatll nginx proxy IP=`ifconfig | awk -F" " '/inet/{print $2}' | head -1` #insyall nginx proxy function install_nginx() { yum remove nginx -y yum install nginx -y touch /etc/nginx/conf.d/proxy.conf cat > /etc/nginx/conf.d/proxy.conf <<EOF upstream web { server 192.168.11.74; server 192.168.11.75; } server { listen 80; server_name $IP; location / { proxy_pass http://web; } } EOF systemctl start nginx } #install nfs server function install_nfs_server() { yum install rpcbind nfs-utils -y [ -d /share ] || mkdir /share && chmod o+w /share echo "/share 192.168.11.62/24(rw,sync,fsid=0)" > /etc/exports systemctl start rpcbind.service systemctl start nfs-server.service } while : do read -p "please choice your install server{nginx|nfs}: " server if [ $server = "nginx" ] then install_nginx elif [ $server = "nfs" ] then install_nfs_server else exit fi done #web01安装nginx web 和nfs客户端 [root@web01 mnt]# cat install_nginx.sh #!/bin/bash #insatll nginx proxy IP=`ifconfig | awk -F" " '/inet/{print $2}' | head -1` #insyall nginx proxy function install_nginx() { yum install nginx -y echo "welcome to web01" >/usr/share/nginx/html/index.html systemctl start nginx } #install nfs server function install_nfs_server() { yum install rpcbind nfs-utils -y systemctl start rpcbind.service systemctl start nfs-server.service mount -t nfs 192.168.11.62:/share /usr/share/nginx/html/ } while : do read -p "please choice your install server{nginx|nfs}: " server if [ $server = "nginx" ] then install_nginx elif [ $server = "nfs" ] then install_nfs_server else exit fi done
2.编写监控脚本,监控nginx、nfs存活状态,内存、磁盘剩余率检测,异常则发送报警邮件
1):发送邮件
#!/usr/bin/python # -*- coding: UTF-8 -*- import sys import smtplib import email.mime.multipart import email.mime.text server = 'smtp.163.com' port = '25' def sendmail(server,port,user,pwd,msg): smtp = smtplib.SMTP() smtp.connect(server,port) smtp.login(user, pwd) smtp.sendmail(msg['from'], msg['to'], msg.as_string()) smtp.quit() print('邮件发送成功email has send out !') if __name__ == '__main__': msg = email.mime.multipart.MIMEMultipart() msg['Subject'] = '你是风儿我是沙,缠缠绵绵回我家' msg['From'] = 'python4_mail@163.com' msg['To'] = 'python4_recvmail@163.com' user = 'python4_mail' pwd = 'sbalex3714' content='%s\n%s' %('\n'.join(sys.argv[1:4]),' '.join(sys.argv[4:])) #格式处理,专门针对我们的邮件格式 txt = email.mime.text.MIMEText(content, _charset='utf-8') msg.attach(txt) sendmail(server,port,user,pwd,msg)
2):copy上面文件到/usr/bin/mail,修改权限chmod+x /usr/bin/mail
3):创建监控脚本servermonitor.sh
#!/bin/sh function ngxMonitor(){ #监控nginx服务 ps aux | grep nginx| grep -v grep &>/dev/null if [ $? -ne 0 ];then msg="TIME:$(date +%F_%T) HOSTNAME:$(hostname) IPADDR:$(/usr/sbin/ifconfig |awk 'NR==2{print $2}') MSG:Nginx program is crash, Waiting to restart" echo $msg /usr/bin/my_mail $msg systemctl restart nginx fi } function nfsMonitor(){ #监控nfs服务 ps aux | grep nfs| grep -v grep &>/dev/null if [ $? -ne 0 ];then msg="TIME:$(date +%F_%T) HOSTNAME:$(hostname) IPADDR:$(/usr/sbin/ifconfig |awk 'NR==2{print $2}') MSG:NFS program is crash, Waiting to restart" echo $msg /usr/bin/my_mail $msg systemctl restart nginx fi } function memMonitor(){ #监控内存 mem_use=`free | awk 'NR==2{print $3}'` mem_total=`free | awk 'NR==2{print $2}'` mem_per=`echo "scale=2;$mem_use/$mem_total"|bc -l |cut -d . -f2` if [ ! -e /usr/bin/bc ];then yum install bc -y -q echo "bc install successful" fi if (( $mem_per > 10 )); then msg="TIME:$(date +%F_%T) HOSTNAME:$(hostname) IPADDR:$(/usr/sbin/ifconfig |awk 'NR==2{print $2}') MSG:Memory usage exceeds the limit,current value is ${mem_per}%" echo $msg /usr/bin/my_mail $msg fi } function diskMonitor(){ #监控磁盘 space_use=`df $disk |awk 'NR==2{print $5}'|cut -d% -f1` if [ $space_use -gt 80 ];then msg="TIME:$(date +%F_%T) HOSTNAME:$(hostname) IPADDR:$(/usr/sbin/ifconfig |awk 'NR==2{print $2}') MSG:Disk space usage exceeds the limit,current value is ${space_use}%" echo $msg /usr/bin/my_mail $msg fi } ngxMonitor &>>/tmp/monitor.log nfsMonitor &>>/tmp/monitor.log memMonitor &>>/tmp/monitor.log diskMonitor &>>/tmp/monitor.log
3.编写计划任务,定时运行监控脚本,完成监控操作
* * * * * /shell/sysCheck.sh