shell 脚本
条件测试
echo $? 为0正确 非0错误
&& 前面的命令执行成功才会执行后面的命令 且
|| 前面的命令执行失败才会执行后面的命令 或
;前后任务没有逻辑关系,执行了前面的目录,在执行后面
-eq 等于
-ne 不等于
-gt 大于
-ge 大于等于
-lt小于
-le小于等于
例如:编写脚本 每2分钟检查系统登录的用户数量,如果超过三人,则发邮件警告
解释:检查当前登录系统的用户:who
统计数量:wc -l
那么定义一个变量 x=$(who | wc -l)
如果超过三人 那么就是 x -gt 3
发邮件 打印内容发送到指定邮箱 echo "有多人使用服务器,请检查" | mail -s test root
那么脚本内容为 vim a.sh
#! /bin/bash
x=$(who | wc -l)
[ $x -gt 3 ] && echo "有多人使用服务器,请检查" | mail -s test root
每两分钟检查一次 计划任务
crontab
*/2 * * * * bash /root/a.sh
-e 判断后面的文件(包含文件目录及文件)是否存在
-f 判断后面的普通文件是否存在
-d 判断后面的目录是否存在
!不等于
-r 判断后面文件是否有读的权限
-w判断后面文件是否有写的权限
-x判断后面文件是否有执行的权限
==等于
!=不等于
-z检查变量是否为空
! -z ==-n 检查变量不为空
注意: 变量最好加双引号
例如 判断是否是目录
[ -d /var/log ] && echo "是目录" || echo "不是目录"
[ -d /etc/fstab ] && echo "是目录" || echo "不是目录"
[ -d / i.txt] && echo "是目录" || echo "不是目录"
判断是否是文件
[ -f /i.txt ] && echo "是文件" || echo "不是文件"
[ -f /etc/fstab ] && echo "shi" || echo "bushi"
if选择结构
if单分支
if 条件测试 ;then
命令序列
fi
或者
if 条件测试
then
命令序列
fi
例如:输入你的用户名,如果用户名为空,-z 查看是否为空,那么执行命令序列
read -p "请输入你的用户名" u
if [ -z $u ] ;then
echo "必须输入用户名"
exit
fi
if 双分支
if 条件测试;then
命令序列1
else
命令序列2
fi
ping 命令的选项
-c n n为自定义的数字例如 ping -c 3 ip ,指定这个ip值ping三次
-i n n为自定义的数字,调节ping的时间频率,默认1sping一次,例如 ping -i 0.2 ip 指定ping这个ip0.2sping一次
-W n ping不通的ip不会立刻返回不通信息,-W n n为自定义数字,快速返回不通信息。例如 ping -W 1 ip 指定ping这个IP如果不通返回信息时间
练习 双分支:查看 192.168.1.11ip是否能通
#! /bin/bash
x="192.168.1.11"
ping -c 3 -i 0.2 -W 1 $x &> /dev/null
if [ $? -eq 0 ]; then
echo" $x is up"
else
echo "$x is down"
fi
if 多分支
第一个条件测试成功了,直接执行命令序列1,如果不满足,去匹配第二个条件测试,以此类推,都没满足,执行else的条件序列
if 条件测试;then
命令序列1
elif 条件测试;then
命令序列2
elif 条件测试;then
命令序列3
else
命令序列4
fi
RANDOM :随机数
[root@localhost ~]# echo $RANDOM
1134
[root@localhost ~]# echo $RANDOM
32070
[root@localhost ~]# echo $RANDOM
14849
取余最大数不会超过除数
所以 生成十以内的随机数为echo $[ RANDOM%10 ]
练习:猜10以内的数字
#!/bin/bash
x=$(echo $[ RANDOM%10 ])
read -p "请输入一个数字 :(0-10)" n
if [ $x -eq $n ]; then
echo "你真棒,猜对了"
elif [ $x -gt $n ];then
echo "你猜大了"
else
echo "你猜小了"
fi
练习: 请输入你的成绩,100分为A+,大于等于90为A,大于等于80为B,大于等于70为B-,大于等于60为C,60以下为D
#!/bin/bash
read -p "请输入你的成绩:(0-100)" n
if [ $n -eq 100 ] ; then
echo "太棒了,A+"
elif [ $n -ge 90 ];then
echo "也很棒哦,A"
elif [ $n -ge 80 ];then
echo "不错哦,B"
elif [ $n -ge 70 ];then
echo "不错哦,B-"
elif [ $n -ge 60 ];then
echo "还需要加油哦,C"
else
echo "需要多多努力,D"
fi
for循环
for 变量名 in 值列表
do
命令序列
done
{1…10} :代表1递增到10
例如 touch abc{1…10}
会创建 abc1-abc10,总共十个文件
seq 排序,按照内容一行显示
例如
[root@localhost ~]# seq 10
1
2
3
4
5
6
7
8
9
10
seq 也支持变量
例如$(seq $i)
练习: 批量ping 192.168.1.1-12这IP
#! /bin/bash
for i in {1..14};
do
ping 192.168.1.$i -c 2 -i 0.5 -W 1 &> /dev/null
if [ $? -eq 0 ];then
echo "192.168.1.$i is up"
else
echo "192.168.1.$i is down"
fi
done
练习: 如何在上述练习中,显示通了多少台,不通多少台.ping ip结果输出到/root/1.txt下
:设置两个变量 ,a=0(代表通的),b=0
在通的语句下,自增a++ 不通的语句下自增b++
最后done之后打印 echo “ a 台通了, a 台通了, a台通了,b 台不通”
#! /bin/bash
a=0
b=0
for i in {1..14};
do
ping 192.168.1.$i -c 2 -i 0.5 -W 1 &> /dev/null
if [ $? -eq 0 ];then
echo "192.168.1.$i is up"
let a++
else
echo "192.168.1.$i is down"
let b++
fi >> /root/1.txt
done
echo "$a 台通了,$b 台不通"
while循环
while 条件测试
do
任务序列
done
只要满足条件测试,就会一直循环这个任务序列
whil :
do
任务序列
done
只要任务序列没有停止语句,while循环就会一直持续
例如 :1等于1 输出nb
#!/bin/bash
while [ 1 -eq 1 ]
do
echo "nb"
done
因为1=1不会出错,所以会一直不停止输出nb
#!/bin/bash
while :
do
echo "nb"
sleep 0.2
done
sleep 1 休息1秒在执行: 可以增加到whil循环下:不过休息1s是比较久的可以零点几秒就行
练习: 猜10以内的数字,一直猜,直到猜对
#!/bin/bash
x=$[RANDOM%10]
while :
do
read -p " 请输入一个数字:(0-10)" n
if [ $x -eq $n ];then
echo "猜对了"
exit
elif [ $n -gt $x ];then
echo "猜大了"
else
echo "猜小了"
fi
done
exit 终止脚本程序
break 跳出循环,执行循环后任务
示例
exit
#!/bin/bash
x=0
while :
do
read -p "请输入数字(0是结束) " n
[ $n -eq 0 ] && exit
let x+=n
done
执行0之后直接退出,不会显示算法结果 let x+=n:每一次循环给x加n一次
break
#!/bin/bash
x=0
while :
do
read -p "请输入数字(0是结束) " n
[ $n -eq 0 ] && break
let x+=n
done
echo "所有数字之和是$x"
执行0之后会执行循环之后的任务
continue 结束循环,进行下一次循环
continue
#!/bin/bash
for i in {1..20}
do
x=$[i%6]
[ $x -ne 0 ] && continue 余数不为0,结束这次循环,进行下一次循环
xx=$[i+10]
echo "$xx"
done
case分支
简化版的if,代码编写比if精简,但功能不如if强大
case 变量 in
模式1)
命令序列;;
模式2)
命令序列;;
*)(结束时写这个)
命令序列;;
esac
示例: 输入你的用户名:
#!/bin/bash
read -p "请输入你的用户名:" i
case $i in
aa)
echo "aaaa"
;;
bb)
echo "bbbb"
;;
*)
echo "没有这个用户"
;;
esac
)里面的内容可以用|增加
例如
#!/bin/bash
read -p "请输入你的用户名:" i
case $i in
aa|A|AA|12|13)
echo "aaaa"
;;
bb)
echo "bbbb"
;;
*)
echo "没有这个用户"
;;
esac
示例: 编写一键安装启动nginx服务的脚本
上传nginx 包到/root/nginx
#!/bin/bash
yum install -y gcc openssl-devel pcre-devel make gcc-c++
tar zxf /root/nginx/nginx-1.20.1.tar.gz
cd nginx-1.20.1
./configure
make && make install
cd /usr/local/nginx/sbin/
./nginx
测试脚本成功没有
查看端口号 80 是否是nginx
打开浏览器输入主机地址是否出现nginx界面
如果服务打开了,没有显示nginx界面,检查防火墙
netstat 查看端口号说明
-n 以数字格式显示端口号
-t显示tcp连接的端口
-u显示udp连接的端口
-l 显示正在监听的端口信息
-p显示监听的端口名称是什么
-a显示有效的连接信息,包括已建立的连接,也包括监听请求连接
常见组合: netstat -anpt
netstat -anpu
字符串截取
${} 表达式
例如
[root@localhost ~]# a=1122344
[root@localhost ~]# echo ${a:3:2}
23
例如${a:3:2} : ${}里的a是指明a这个变量,3是代表从第三个字符开始截取(如果没有指定默认从第一个开始),2截取2个字符
随机截取一个随机数
#!/bin/bash
a=adadufhaiahdadai
x=$[ RANDOM%17 ] 定义一个a的取值访问的随机数(a有16位数,定义随机数位0到16之间)
echo ${a:x:1} 随机截取