信号
linux通过信号来在运行在系统上的进程之间通信 ,也可以通过信号来控制shell脚本的运行
(1)捕捉信号(trap命令)
常用信号: ctrl+c 表示终止进程,ctrl+z 表示暂停过程
#将信号2(ctrl+c)更改为输出westos
[root@localhost ~]# trap "echo westos" 2
[root@localhost ~]# ^Cwestos
#恢复信号
[root@localhost ~]# trap : 2
[root@localhost ~]# ^C
[root@localhost ~]# stty -a
#信号屏蔽;此时按ctrl+c便会失效
[root@localhost ~]# trap "" 2
#信号恢复
[root@localhost ~]# trap : 2
[root@localhost ~]# ^C
[root@localhost mnt]# vim 01_trap.sh
#####################
#!/bin/bash
trap "echo 'Sorry: I have trappedd Ctrl+c' " 2 ##捕捉信号
echo "This is a test script"
count=1
while [ $count -le 10 ] ## $count为1-10
do
echo "Loop #$count"
sleep 2
count=$[ $count + 1 ]
done
echo "This is the end of the script"
trap - 2 ## - 或者 : 都表示恢复信号
echo "I just removed the trap"
[root@localhost mnt]# sh 01_trap.sh
[root@localhost mnt]# vim 02_trap.sh
#####################
#!/bin/bash
trap "echo ByeBye" EXIT ## 捕捉信号
count=1
while [ $count -le 5 ] ## $count表示1-5
do
echo "Loop #$count"
sleep 2
count=$[ $count + 1 ]
done
[root@localhost mnt]# sh 02_trap.sh
(2)捕捉脚本的退出
xargs命令:获取上一条命令结果全部输出到一行
[root@localhost mnt]# vim test
[root@localhost mnt]# cat test
1 2 3 4
5 6 7 8
#将文件内容输出到一行
[root@localhost mnt]# cat test | xargs
1 2 3 4 5 6 7 8
# 将文件内容每两个输出到一行
[root@localhost mnt]# cat test | xargs -n2
1 2
3 4
5 6
7 8
练习1:
编写脚本,让系统一直在/tmp目录下建立文件,捕捉信号2( ctrl+c)当执行 ctrl+c 时,删除刚才建立的所有文件
[root@localhost mnt]# date +%F-%H:%M:%S
2018-12-30-15:30:47
[root@localhost mnt]# touch /tmp/westos{1..5}
[root@localhost mnt]# ls /tmp
[root@localhost mnt]# find /tmp -path */westos* -exec rm -rf {} \;
[root@localhost mnt]# ls /tmp
[root@localhost mnt]# vim trap_01.sh
#####################
#!/bin/bash
#trap "find /tmp -type f -name "westos_*" | xargs rm -rf && exit" 2
trap "find /tmp -path */westos_* -exec rm -rf {} \; && exit" 2 # 执行ctrl+c便会删除文件
# 执行脚本便会自动建立文件
while true
do
touch /tmp/westos_$(date +%F-%H:%M:%S)
sleep 2
ls -l /tmp/westos_*
done
注释: xargs 和 -exec 的执行效果是一样的,后边跟执行的命令
[root@localhost mnt]# sh trap_01.sh
练习2:
编写脚本,使得仅有3次机会连接失败本机ip,超过3次便加入到黑名单中
分析:
查看日志,找到连接失败的ip与失败次数,并将超过3次的ip导入ssh连接的黑名单中
#清空日志
[root@localhost mnt]# > /var/log/secure
[root@localhost mnt]# cat /var/log/secure
#4次ssh连接失败
[kiosk@foundation66 Desktop]$ ssh root@172.25.254.166
#查看日志
[root@localhost mnt]# cat /var/log/secure
#1.过滤出含有ip的行
[root@localhost mnt]# cat /var/log/secure | grep Failed
#2.截取ip
[root@localhost mnt]# cat /var/log/secure | grep Failed | awk '{ print $11 }'
172.25.254.66
172.25.254.66
172.25.254.66
172.25.254.66
#3.统计次数并排序
[root@localhost mnt]# cat /var/log/secure | grep Failed | awk '{ print $11 }' | sort | uniq -c
4 172.25.254.66
#4.按照指定的规则输出;必须转换格式!
[root@localhost mnt]# cat /var/log/secure | grep Failed | awk '{ print $11 }' | sort | uniq -c | awk '{ print $1 ":" $2 }'
4:172.25.254.66
#拒绝66主机ssh连接本机
[root@localhost mnt]# vim /etc/hosts.deny
#####################
sshd:172.25.254.66
[root@localhost mnt]# vim /etc/hosts.deny
还原:
[root@localhost mnt]# vim /etc/hosts.deny
#####################
删除: sshd:172.25.254.66
编写脚本:
[root@localhost mnt]# vim ssh_deny.sh
#####################
#!/bin/bash
cat /var/log/secure | grep Failed | awk '{ print $11 }' | sort | uniq -c | awk '{ print $1 "=" $2 }' > /tmp/blacklist ##将按规定格式截取的ip和次数都导入到文件中
MAXCOUNT="3" ##定义变量
for i in `cat /tmp/blacklist` ##遍历整个文件
do
IP=`echo $i | awk -F= '{print $2}'` ##获取主机ip
COUNT=`echo $i | awk -F= '{print $1}'` ##获取失败次数
if [ $COUNT -gt $MAXCOUNT ];then ##判断连接失败次数是否超过3次
grep $IP /etc/hosts.deny &> /dev/null
if [ $? -ne 0 ];then ##判断要屏蔽的IP之前是否已经屏蔽过
echo "sshd:$IP" >> /etc/hosts.deny
fi
fi
done
测试:
#执行脚本
[root@localhost mnt]# sh ssh_deny.sh
#发现自动加入了66主机ip,因为刚刚已经错误连接了4次本机
[root@localhost mnt]# cat /etc/hosts.deny
[kiosk@foundation66 Desktop]$ ssh root@172.25.254.166
ssh_exchange_identification: read: Connection reset by peer