shell 100例
1、每天写一个文件
(题目要求)
·请按照这样的日期格式(xxxx-xx-xx每日生成一个文件
·例如生成的文件为2017-12-20.log,并且把磁盘的使用情况写到到这个文件中·不用考虑cron,仅仅写脚本即可
[核心要点]
date命令用法
df命令
知识补充:date
#!/bin/bash
date=`date +%F`
dir=/root/shell/disklog
if [ ! -d $dir ]
then
mkdir -p $dir
fi
df -h > $dir/$date.log
find $dir/ -mtime +365 |xargs rm -rf
2、根据日志统计访问量
2409:8c5b:ffff:2802::12|18/Sep/2023:14:54:58 +0800]|GET /StorageWeb/servlet/GetFileByURLServlet?dm=D950&root=/mnt/wfs210&pt=/db0/3c&fileid=L0db03c39ca7fe50189f50b7c5fdefbf59.m4a&type=3&ui=MTAwcG41ak4xMzg4&ci=0a0LLEGN1559034202309151704013v4&cn=15717012094+2023-09-...&ct=2&time=1695020117&exp=86400&code=C8C83177ED3323F4868218945448B338B844839D2A270E2B718187A6538AB607&ec=1&bucketName=hcy-dg-21 HTTP/1.1|0.137|200|507533|-|migu/mCloud10.2.1 (Linux;Android 8.0.0) ExoPlayerLib/2.11.4
2409:8c5b:ffff:2802::12|18/Sep/2023:14:55:00 +0800]|GET /StorageWeb/servlet/GetFileByURLServlet?dm=D950&root=/mnt/wfs210&pt=/cc6/65&fileid=L2cc665e6961e4596c9db5cedf98ab1e4b.m4a&type=3&ui=MTAwcG41ak4xMzg4&ci=0a0LLEGN1559070202309151703581do&cn=18296193091+2023-09-...&ct=2&time=1695020117&exp=86400&code=5B417BF97BF91525AF08146323BB065D05559AE2FA68C645CD115BDC33CBCF4B&ec=1&bucketName=hcy-dg-21 HTTP/1.1|0.090|200|1154259|-|migu/mCloud10.2.1 (Linux;Android 8.0.0) ExoPlayerLib/2.11.4
10.19.2.55|18/Sep/2023:14:55:19 +0800]|GET /StorageWeb/servlet/GetFileByURLServlet?dm=D953&root=/mnt/wfs203&pt=/7fd/24&fileid=LB7fd2451f123d64eb80416987e3a1e5b7.mp3&type=3&ui=MDEwSFVwNFIxNzU5&ci=010HUp4R175914520220323113403bai&cn=%E9%83%91%E4%B8%AD%E5%9F%BA+-+%E6%A2%A6%E9%86%92%E6%97%B6%E5%88%86&ct=2&time=1695009524&exp=86400&code=AF1B6990923437217D271AA102149FDF6EC9C58F56C057F7FB61FB77C6C4E317&ec=1 HTTP/1.1|0.049|206|1|-|mCloud_iPhone/09051207 CFNetwork/1390 Darwin/22.0.0
统计出每个IP访问量有多少
核心要点
awk、sort、uniq命令
sudo cat /usr/local/c3ms/logs/access.log | awk -F "|" '{print $1}' | sort | uniq -c | sort -n -r | more
3、统计所有进程占内存之和
题目要求
写一个脚本计算一下linux系统所有进程占用内存大小的和。
核心要点
ps命令用法
for循环
加法运算
#!/bin/bash
sum=0
for n in `ps -aux | grep -v COMMAND | awk '{print $6}'`
do
sum=$[$sum + $n]
done
echo $sum
4、检查机器存活
设计一个脚本,监控远程的一台机器(假设ip为180.163.26.39)的存活状态,并将主机是否通的信息打印到前台信息
#!/bin/bash
IP=$1
n=`ping -c2 $IP | grep "packets" | awk -F '%' '{print $1}' | awk '{print $NF}'`
if [ $n -ge 50 ];then
echo "该主机死机"
else
echo "该主机通"
fi
5、批量修改文件名称
- 1、找到/123目录下所有后缀名为.txt的文件1.批量修改txt为.txt.bak
- 2、把所有bak文件打包压缩为123.tar.gz3.批量还原文件的名字,即把增加的.bak再删除
- [核心要点]
find用来查找所有.txt文件
tar打包一堆文件
还原文件名用for循环
#!/bin/bash
#第一种写法
find /123 -type f -name "*.txt" > /123/txt.list
for f in `cat /123/txt.list`
do
mv $f $f.bak
done
#第二种写法
#find /123 -type f -name "*.txt" | xargs -i mv {} {}.bak
#find /123 -type f -name "*.txt" -exec mv {} {}.bak \;
for f in `cat /123/txt.list`
do
echo $f.bak
done > /123/txt.bak.list
tar -czvf 123.tar.gz `cat /123/txt.bak.list | xargs `
6、检查本地的80端口是否开启
题目要求:
写一个脚本,判断本机的80端口(假如服务为httpd)是否开启着,如果开启着什么都不做,如果发现端口不存在,那么重启一下httpd服务,并发邮件通知你自己。脚本写好后,可以每一分钟执行一次,也可以写一个死循环的脚本,30s检测一次。
核心要点:
检测80端口使用nmap-p 80 127.0.0.1或者netstat -ntplgrep -w 80
重启httpd服务的命令要知道 systemctl restart httpd
利用死循环
#!/bin/bash
m=10288226404@qq.com
while :
do
n=`netstat -ntulp | grep ":80 " | wc -l`
if [ $n -eq 0 ]
then
systemctl restart nginx
# python main.py $m "80端口关闭,已经将nginx进行重启操作"
fi
sleep 20
done
7 、 数据库备份
*题目要求
设计一个shell脚本来备份数据库,首先在本地服务器上保存一份数据,然后再远程拷贝份,本地保存一周的数据,远程保存一个月。假定,我们知道mysqlroot账号的密码,要备份的库为discuz,本地备份目录为/bak/mysql,远程服务器ip为192.168.123.30,远程提供了一个rsync服务,备份的地址是192168.123.30:backup.写完脚本后,需要加入到cron中,每天凌晨3点执行。
- 核心要点
备份数据库的命令
同步到远程去的命令
命名规则
#!/bin/bash
d1=`date +%w`
d2=`date +%d`
loca_bakdir=/bak/mysgl
remote_bakdir=192.168.123.30::backup
exec 1> /tmp/mysglbak.log 2>/tmp/mysglbak.err
echo"mysql bakcup begin at `date`"
mysqldump -uroot -pxxxx discz > $local bakdir/discuz.sql.$d1
rsync -az $local_bakdir/discuz.sql.$dl $remote_bakdir/discuz.sql.$d2
echo "mysql backup end at `date`"
8、检查502状态码
- 背景
服务器上跑的是LNMP环境,近期总是有502现象。502为网站访问的状态码,200正常,502错误是nginx最为普遍的借误状态码。由于502只是暂时的,并且只要一重启php-fpm服务则502消失但不重启的话,则会一直持续很长时间。所以有必要写一个监控脚本,监控访问日志的状态码,旦发生502,则自动重启一下php-fpm。
我们设定:
- access log /data/log/access.log
- 脚本死循环,每10s检测一次(假设每10s钟的日志条数为300左右
- 重启php-fpm的方法是 /etc/init.d/php-fpm restart
- 技术核心
使用curl检测状态码是否是502或者通过分析访问日志判断状态码的比率,
重启php-fpm服务的命令。
#!/bin/bash
log=/data/log/access.log
while :
do
502_n=`tail -n 300 $log | grep -c '502/'`
if [ -z "$502_n" ]
then
exit
fi
if [ "$502_n" -gt 100 ]
then
/etc/init.d/php.fpm > /dev/null 2>/tmp/php.fpm.err
fpm_p_n=`pgrep -l php.fpm | wc -l `
if [ $fpm_p_n -eq 0 ]
then
python main.py xxx@xx.com "php.fpm重启失败 " "head -10 /tmp/php.fpm.err"
exit
fi
fi
sleep 10
done
9、删除文件中包含字母的行
- 背景:
把一个文本文档的前5行中包含字母的行删除掉,同时把6到10行中的全部字母删除掉。 - 技术要求
使用sed
#!/bin/bash
sed -n '1,5p' /opt/shell/9.txt | sed '/[a-zA-Z]/d'
sed '1,5d' /opt/shell/9.txt | sed '1,5s/[a-zA-Z]/g'
10、找单词
-
题目要求
用shell打印下面这句话中字母数小于6的单词。
Bash also interprets a number of multi-character options. -
[核心要点]
for循环遍历所有单词 wc-l 获取字符串长度
for w in Bash also interprets a number of multi-character options. ; do echo $w ;done
echo Bash also interprets a number of multi-character options. | awk -F '[ +-.]' '{print NF}'
#!/bin/bash
c="Bash also interprets a number of multi-character options."
n=`echo $c | awk -F '[ +-.]' '{print NF}'`
for ((i=l;i<$n;i++))
do
l=`echo $c | awk -F '[ +-.]' -v j=$i '{print $j}'| wc -L`
if [ $l -lt 6 ]
then
echo $c | awk -F '[ +-.]' -v j=$i '{print $j}'
fi
done
11、输入数字运行命令
- [题目要求]
写一个脚本实现如下功能:
输入一个数字,然后运行对应的一个命令显示命令如下:
cmd meau* 1 - date 2 - ls 3 - who 4 - pwd当输入1时,会运行date,输入2时运行ls,以此类推 - [核心要点]
case判断
#/bin/bash
echo "*cmd meau** 1 - date 2 - ls 3 - who 4 - pwd"
read -p "Please input a number: " n
if [ -z "$n" ]
then
echo "请输入一个1-4的数字"
fi
n1=`echo $n | sed 's/[0-9]//g'`
if [ -n $n1 ]
then
echo "请输入一个纯数字,范围1-4"
fi
case $n in
1)
date
;;
2)
ls
;;
3)
who
;;
4)
pwd
;;
*)
echo "请输入一个纯数字,范围1-4"
;;
esac
12、批量创建用户
用shell脚本实现如下需求:
添加user_00 – user_09 10个用户,并且给他们设置一个随机密码,密码要求10位包含大小写字母以及数字,注意需要把每个用户的密码记录到一个日志文件里。
提示:
- 随机密码使用命令 mkpasswd
- 在脚本中给用户设置密码,可以使用echo 然后管道passwd命令
- 核心要点
- seq实现数字递增
- mkpasswd产生随机字符
1、 安装mkpasswd命令
yum -y install expect-5.45-14.el7_1.x86_64
设置10个随机数字
mkpasswd -l 10 -s 0
#!/bin/bash
for i in `seq -w 00 09`
do
useradd user_$i
p=`mkpasswd -l 10 -s 0 `
echo "user_$i $p" >> /tmp/pass.tmp
echo $p |passwd --stdin user_$i
done
13、监控apache
题目要求
在服务器上,写一个监控脚本,要求如下:
- 每隔10s去检测一次服务器上的httpd进程数,如果大于等于500的时候,就需要自动重启一下apache服务,并检测启动是否成功?
- 若没有正常启动还需再一次启动,最大不成功数超过5次则需要立即发邮件通知管理员,并且以后不需要再检测!
- 如果启动成功后,1分钟后再次检测httpd进程数,若正常则重复之前操作(每隔10s检测一次),若还是大于等于500,那放弃重启并需要发邮件给管理员,然后自动退出该脚本。假设其中发邮件脚本为之前使用的mail.py
核心要点
- pgrep -l httpd或者ps -C httpd --no-heading检查进程
- for循环5次计数器
101 自动屏蔽攻击IP:增强您的服务器安全性的有效策略
在当今的数字世界中,服务器安全性成为了每个企业或个人都必须面对的重要议题。特别是当面对如DoS(拒绝服务)攻击等网络威胁时,一个有效的防范措施显得尤为关键。本文将探讨如何通过自动屏蔽攻击IP来增强您的服务器抵御DoS攻击的能力,并提供一个实用的Bash脚本作为参考。
理解DoS攻击
DoS攻击是一种恶意行为,通过向目标服务器发送大量无用的请求,耗尽其资源,使合法用户无法访问服务。这种攻击不仅影响服务器的正常运行,还可能导致数据丢失、系统崩溃等严重后果。
自动屏蔽攻击IP的策略
为了有效应对DoS攻击,我们需要一个能够实时监控服务器流量,并自动识别和屏蔽攻击IP的系统。以下是实现这一目标的基本步骤:
1、监控服务器日志:通过分析Nginx等服务器的访问日志,我们可以识别出异常流量模式,如短时间内来自同一IP的大量请求。
2、识别攻击IP:使用脚本或工具对日志数据进行处理,提取出那些行为异常的IP地址。
3、自动屏蔽:一旦发现攻击IP,立即使用iptables等防火墙工具将其加入黑名单,阻止其进一步的访问。
4、记录和报告:将屏蔽的IP地址和时间记录在日志文件中,以便后续分析和报告。
#!/bin/bash
# 定义日志文件路径和临时黑名单文件路径
LOG_FILE=/usr/local/nginx/logs/demo2.access.log
BLACKLIST_FILE=/tmp/blacklist.txt
DROP_LOG=/tmp/drop_ip.log
# 获取当前时间并格式化为日期
DATE=$(date +"%d/%b/%Y:%H:%M")
# 从日志文件中提取异常IP地址(这里假设每分钟超过10个请求的IP为异常)
tail -n 5000 $LOG_FILE | grep "$DATE" | awk '{print $1, $4}' | sort -n | uniq -c | awk '$1 > 10 {print $2}' > $BLACKLIST_FILE
# 读取黑名单文件,并屏蔽这些IP地址
while IFS= read -r IP; do
if ! iptables -vnL INPUT | grep -q "$IP"; then
iptables -I INPUT -s "$IP" -j DROP
echo "$(date +'%F_%T') $IP" >> $DROP_LOG
echo "Blocked IP: $IP"
fi
done < $BLACKLIST_FILE
# (可选)清理过时的iptables规则,避免规则过多导致性能下降
# 这里可以根据需要添加逻辑来定期清理旧的屏蔽规则
脚本说明
脚本首先定义了所需的文件路径和日期格式。
使用tail和grep命令结合当前时间从Nginx访问日志中提取最近的访问记录。
通过awk和sort命令处理这些记录,识别出每分钟请求次数超过10次的IP地址,并将它们写入临时黑名单文件。
脚本接着读取黑名单文件中的每个IP地址,并使用iptables命令将它们加入INPUT链的DROP目标中,从而屏蔽这些IP的访问。同时,将屏蔽操作记录在日志文件中。
最后,您可以根据需要添加额外的逻辑来定期清理iptables中的旧规则,以保持防火墙的性能。
请注意,此脚本是一个基本示例,可能需要根据您的服务器配置、日志格式和安全策略进行定制。在实际使用中,还应考虑脚本的性能影响、错误处理和日志管理等方面的问题。
脚本2:
#!/bin/bash
log=/data/nginx/access.log
#
function add_iptables()
{
while read line
do
ip=$(echo $line | awk '{print $2}')
count=$(echo $line | awk '{print $1}')
rule_count=$(iptables -L -n | grep "$ip" | wc -l)
if [ $count -gt 100 ] && [ $rule_count -eq 0 ]; then
iptables -I INPUT -s $ip -j DROP
echo "$ip is dropped" >> /tmp/droplist.log
fi
done < $log
}
function main()
{
add_iptables
}
main
脚本3:
#!/bin/bash ################################################################################ ####
#根据web访问日志,封禁请求量异常的IP,如IP在半小时后恢复正常,则解除封禁 ################################################################################ ####
logfile=/data/log/access.log
#显示一分钟前的小时和分钟
d1=`date -d "-1 minute" +%H%M`
d2=`date +%M`
ipt=/sbin/iptables
ips=/tmp/ips.txt
block()
{
#将一分钟前的日志全部过滤出来并提取IP以及统计访问次数
grep '$d1:' $logfile|awk '{print $1}'|sort -n|uniq -c|sort -n > $ips #利用for循环将次数超过100的IP依次遍历出来并予以封禁
for i in `awk '$1>100 {print $2}' $ips`
do
$ipt -I INPUT -p tcp --dport 80 -s $i -j REJECT
echo "`date +%F-%T` $i" >> /tmp/badip.log
done
}
unblock()
{ #将封禁后所产生的pkts数量小于10的IP依次遍历予以解封
for a in `$ipt -nvL INPUT --line-numbers |grep '0.0.0.0/0'|awk '$2<10 {print
$1}'|sort -nr`
do
$ipt -D INPUT $a
done
$ipt -Z
}
#当时间在00分以及30分时执行解封函数
if [ $d2 -eq "00" ] || [ $d2 -eq "30" ]
then #要先解再封,因为刚刚封禁时产生的pkts数量很少 unblock
block
else
block
fi
101 监控网站的URL
#!/bin/bash
URL_LIST="www.baidu.com www.ctnrs.com www.der-matech.net.cn www.der-matech.com.cn www.der-matech.cn www.der-matech.top www.der-matech.org"
for URL in $URL_LIST; do
FAIL_COUNT=0
for ((i=1;i<=3;i++)); do
curl -s --head http://$URL > /dev/null
HTTP_CODE=$(curl -o /dev/null --connect-timeout 3 -s -w "%{http_code}\n" http://$URL)
if [ $HTTP_CODE -eq 200 ]; then
echo "$URL OK"
break
else
echo "$URL retry $FAIL_COUNT"
let FAIL_COUNT++
fi
done
if [ $FAIL_COUNT -eq 3 ]; then
echo "Warning: $URL Access failure!"
echo "网站$URL坏掉,请及时处理" | mail -s "$URL网站高危" 1242253055@qq.com
fi
done
102 利用sshpass远程登陆主机,并执行命令
#/bin/bash
if [ -z $1 ]; then
echo "usage: $0 command"
exit 1
fi
HOST_LIST_FILE=host_list.txt # 这个修改$1
COMMAND=$@ ## 这个修改$2
for IP in $(awk '/^[^#]/{print $1}' $HOST_LIST_FILE); do
USER=$(awk -v I=$IP 'I==$1{print $2}' $HOST_LIST_FILE)
PASS=$(awk -v I=$IP 'I==$1{print $3}' $HOST_LIST_FILE)
PORT=$(awk -v I=$IP 'I==$1{print $4}' $HOST_LIST_FILE)
echo "-----$IP------"
sshpass -p "$PASS" ssh -p "$PORT" "$USER@$IP" "$COMMAND"
done
## 核心关键sshpass命令安装
# 源码包安装
wget http://sourceforge.net/projects/sshpass/files/sshpass/1.05/sshpass-1.05.tar.gz
tar xvzf sshpass-1.05.tar.gz
cd sshpass-1.05.tar.gz
./configure
make
make install
# yum安装
yum -y install sshpass
1、脚本闭坑注意事项
第一次登陆,需要手动输入密码,保证对方服务,有认证秘钥
如果是修改密码,需要对过期的秘钥内容进行删除,重新手动输入
2、脚本执行效果
103 你的网站守护神脚本,通过测试URL并返回码
#!/bin/bash
URL_LIST="www.baidu.com www.ctnrs.com www.der-matech.net.cn www.der-matech.com.cn www.der-matech.cn www.der-matech.top www.der-matech.org"
for URL in $URL_LIST; do
FAIL_COUNT=0
for ((i=1;i<=3;i++)); do
curl -s --head http://$URL > /dev/null
HTTP_CODE=$(curl -o /dev/null --connect-timeout 3 -s -w "%{http_code}\n" http://$URL)
if [ $HTTP_CODE -eq 200 ]; then
echo "$URL OK"
break
else
echo "$URL retry $FAIL_COUNT"
let FAIL_COUNT++
fi
done
if [ $FAIL_COUNT -eq 3 ]; then
echo "Warning: $URL Access failure!"
echo "网站$URL坏掉,请及时处理" | mail -s "$URL网站高危" 1242253055@qq.com
fi
done
首先,它定义了一个包含多个网站URL的列表。然后,对每个URL进行循环检测。对于每个网站,脚本会尝试连接并获取HTTP状态码。如果状态码为200,表示网站正常,脚本会打印出“$URL OK”并继续检测下一个网站。如果状态码不是200,则表示网站可能存在问题,脚本会进行重试,并记录失败次数。如果连续三次尝试都失败,那么脚本会发送一封警告邮件,通知你网站可能存在问题
104 使用shell脚本批量清理kubernetes集群中Evicted状态的pod
测试环境有一台宿主机出现了异常,大量的异常日志导致宿主机的磁盘使用率超过了85%,触发了上面的pod驱离策略,该宿主机上的的pod处于Evicted状态。在清理了磁盘之后,得手动处理掉这些Evicted状态的pod。
查看了下该状态的pod数目有50+,一条条的删除到猴年马月,写个shell脚本批量处理下。
#!/bin/bash
## 获取当前状态为Evicted的pod
## 并输出到一个临时文件内
## 这是输出的文件按制表符tab键间隔
#kubectl get pods --all-namespaces | awk '/Evicted/ {print $1 "\t" $2}' > evicted_pods.txt
## 这是输出的文件按空格符间隔
kubectl get pods --all-namespaces | awk '/Evicted/ {print $1 " " $2}' > evicted_pods.txt
## 这是按空格示例,截取文本解析成字段:命名空间和pod名
while IFS=' ' read -r namespace pod_name; do
## 这是按制表符tab键示例,截取文本解析成字段
#while IFS=$'\t' read -r namespace pod_name; do
## 验证命名空间和 Pod 名称是否存在
if [[ ! -z "$namespace" && ! -z "$pod_name" ]]; then
echo "kubectl delete pod $pod_name -n $namespace:"
kubectl delete pod "$pod_name" -n "$namespace"
fi
done < evicted_pods.txt
## 可选是否清理临时文件
rm -f evicted_pods.txt
105、nginx日志分割
#!/bin/bash
# 源日志目录
logs_path="/var/log/nginx"
# 备份日志目录
back_logs_path="${logs_path}/$(date -d 'yesterday' +'%F')"
# 创建备份目录,以日期命名,注意,每天零点整切割,开始记录新的一天的日志,备份目录应该是昨天
mkdir -p ${back_logs_path}
# 重命名旧日志名,注意日期
cd ${logs_path} && find . -type f |xargs -i mv {} {}.$(date -d 'yesterday' +'%F')
# 移动旧日志文件到该目录下
cd ${logs_path} && find . -type f |xargs -i mv {} ${back_logs_path}
# 重新生成新日志
kill -USR1 `cat /var/run/nginx.pid`
106、k8s查看deployment的对应版本号
因版本发布,总是需要查看对应的版本号;编写脚本,只需要在脚本后面添加对应的deployment名称,输出对应的deployment名称和镜像版本。只需将结果发生给开发即可,开发根据进行版本进行ci的构建
#!/bin/bash
for deployment_name in "$@"
do
image_version=$( sudo kubectl get deployment $deployment_name -n prod -o=jsonpath='{.spec.template.spec.containers[*].image}' | awk -F '/' '{print $NF}')
echo " $deployment_name $image_version"
done
#!/bin/bash
"""
逐个处理传入的部署名称,获取它们的镜像版本,并打印出来。
参数:
@ - 传入的所有参数,预期为部署的名称。
返回值:
无
"""
for deployment_name in "$@"
do
# 获取指定部署的镜像版本,-o输出格式是json
image_version=$( sudo kubectl get deployment $deployment_name -n prod -o=jsonpath='{.spec.template.spec.containers[*].image}' | awk -F '/' '{print $NF}')
# 打印部署名称和对应的镜像版本
echo "Deployment: $deployment_name - Image Version: $image_version"
done
- 使用while循环
## 命令1:
echo "deploymnt名称1 deployment名称2" | tr ' ' '\n' | while read -r deployment_name; do image_version=$(sudo kubectl get deployment $deployment_name -n prod -o=jsonpath='{.spec.template.spec.containers[*].image}' | awk -F '/' '{print $NF}'); echo "$deployment_name $deployment_name:$image_version"; done
## 命令2:
echo "deploymnt名称1 deployment名称2" | tr ' ' '\n' | while read -r deployment_name; do image_version=$(sudo kubectl get deployment $deployment_name -n prod -o=jsonpath='{.spec.template.spec.containers[*].image}' | awk -F '/' '{print $NF}'); printf "%-20s %s\n" "$deployment_name" "$deployment_name:$image_version"; done
- 脚本解析
# 该脚本段用于列出指定命名空间中特定部署的名称及其对应的镜像版本号。
# 它首先通过管道传递一个包含多个部署名称的字符串,然后对每个部署名称进行处理,
# 获取对应的镜像版本号,并以部署名称和版本号的形式打印出来。
echo "album-saas-mq yun-album-migration album-saas-manage album-saas-job" | tr ' ' '\n' | while read -r deployment_name; do
# 获取指定部署的镜像版本号
image_version=$(sudo kubectl get deployment $deployment_name -n prod -o=jsonpath='{.spec.template.spec.containers[*].image}' | awk -F '/' '{print $NF}')
# 打印部署名称和对应的镜像版本号
printf "%-20s %s\n" "$deployment_name" "$deployment_name:$image_version"
done
107 k8s批量执行驱赶node节点
for IP in "$@"
do
node_name=$(sudo kubectl get node -o wide | awk 'NR >2 {print $1" " $6}' | grep $IP | awk '{print $1}')
kubectl get pod -A | grep $node_name
kubectl drain $node_name --ignore-daemonsets
echo " $IP is SchedulingDisabled"
done
执行脚本: sh drain-node.sh 192.168.1.202 192.168.1.203 192.168.1.204 ## 输入主机列表,自动将node进行驱赶
108 批量执行多个IP和端口的网络联通性测试
#!/bin/bash
# 检查输入参数
if [ $# -ne 1 ]; then
echo "Usage: $0 <input_file>"
exit 1
fi
input_file=$1
# 检查输入文件是否存在
if [ ! -f $input_file ]; then
echo "Input file not found"
exit 1
fi
# 遍历输入文件中的每行
while IFS= read -r line; do
ip=$(echo $line | awk '{print $1}')
port=$(echo $line | awk '{print $2}')
# 使用 sudo traceroute 测试网络连通性
echo -n "Testing $ip:$port... "
result=$(sudo traceroute -n -T $ip -p $port 2>&1)
if [[ $result == *"Hops"* ]]; then
echo "网络可访问"
else
echo "网络不可访问"
fi
done < $input_file
脚本2:
#!/bin/bash
# 定义要测试的 IP 地址和端口列表
read -p "请输入要测试的IP地址: " IP_LIST
read -p "请输入要测试的端口: " PORT_LIST
IP_LIST=($IP_LIST)
PORT_LIST=($PORT_LIST)
# 循环遍历 IP 地址和端口列表
for ip in "${IP_LIST[@]}"
do
for port in "${PORT_LIST[@]}"
do
echo "Testing connectivity to $ip on port $port"
sudo traceroute -n -T $ip -p $port
echo "-----------------------------------------"
done
done
109 磁盘空间大小和Inode大小监控
- 1、磁盘空间大少
#!/bin/bash
# 检查硬盘,如果剩余空间超过80%,则发送消息
# Tue Aug 2 09:45:56 CST 2016
PATH=/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/wl/bin
export PATH
for RemainingSpace in $(df -h | awk '{print $5}' | grep -v 'Use' | sed -e 's/[%]//g')
do
if [[ $RemainingSpace > 80 ]];then
echo -e "$RemainingSpace"
echo -e "$(df -h | grep $RemainingSpace)" > /service/script/.HarddiskWarning
mail -s "disk Warning" wl < /service/script/.HarddiskWarning
fi
done
#!/bin/bash
# 检查磁盘使用情况,如果超过80%则发送警报
THRESHOLD=80
df -h | awk -v threshold="$THRESHOLD" '{ if($5+0 > threshold) print $0; }' | while read output;
do
echo "磁盘使用警报: $output"
done
#!/bin/bash
# 检查磁盘空间,如果根分区使用率超过80%,则发送警告邮件
THRESHOLD=80
EMAIL="admin@example.com"
df -h | grep -q "/dev/root"
if [ $? -eq 0 ]; then
USAGE=$(df -h | grep "/dev/root" | awk '{ print $5 }' | sed 's/%//g')
if [ $USAGE -ge $THRESHOLD ]; then
echo "警告:根分区使用率已达 $USAGE%" | mail -s "磁盘空间警告" "$EMAIL"
fi
fi
- 3、INode大小监控
#!/bin/bash
# 检查Inode:如果空闲的Inode少于200,则发送消息给wl
# Tue Aug 2 10:21:29 CST 2016
PATH=/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/wl/bin
export PATH
# 循环检查每个文件系统的空闲Inode数量
for FreeInode in $(df -i | grep -v "Filesystem" | awk '{print $4}')
do
# 如果空闲Inode少于200,则执行以下操作
if [[ $FreeInode < 200 ]];then
# 将包含空闲Inode数量少于200的文件系统信息写入文件
echo -e "$(df -i | grep "$FreeInode")" > /service/script/.FreeInode
# 发送警告邮件给wl,邮件内容为包含空闲Inode数量少于200的文件系统信息
mail -s "FreeInode Warning" wl < /service/script/.FreeInode
fi
done
110 一键监控CPU,轻松应对性能瓶颈
#!/bin/bash
#Inspect CPU
# 设置环境变量,确保脚本可以正确找到所需的命令
PATH=/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/wl/bin
export PATH
TERM=linux
export TERM
# 使用top命令获取CPU的空闲率,并去掉小数点及后面的数字,只保留整数部分
CpuResult=$(top -bn 1 | grep "Cpu" | awk '{print $5}' | sed 's/\..*$//g')
# 判断CPU的空闲率是否低于20%,如果是,则执行以下操作
if [[ $CpuResult < 20 ]];then
# 将警告信息写入文件
echo "CPU WARNING : $CpuResult" > /service/script/.cpu_in.txt
# 将top命令的输出追加到文件中,以便后续分析
top -bn 1 >> /service/script./cpu_in.txt
# 发送邮件警告
mail -s "Inspect CPU" wl < /service/script/.cpu_in.txt
fi
111 一键监控多台服务器磁盘使用情况
#!/bin/bash
# 设定磁盘使用率的最大阈值,默认为80%
FSMAX="80"
# 设定远程连接的用户名,这里为root
remote_user='root'
# 设定要监控的服务器IP地址列表,替换(IP地址列表)为实际的IP地址,多个IP之间用空格分隔
remote_ip=(IP地址列表)
# 初始化服务器IP地址的索引变量
ip_num='0'
# 循环遍历服务器IP地址列表
while [ "$ip_num" -le "$(expr ${#remote_ip[@]} - 1)"]
do
# 初始化读取行数变量
read_num='1'
# 通过SSH远程连接到服务器,并执行df -h命令获取磁盘使用情况,结果重定向到临时文件
ssh "$remote_user"@"${remote_ip[$ip_num]}" df -h > /tmp/diskcheck_tmp
# 使用grep, awk和sed命令解析磁盘使用情况,提取出各分区的使用率并去除百分号,结果重定向到另一个临时文件
grep '^/dev/*' /tmp/diskcheck_tmp | awk '{print $5}' | sed 's/\%//g' > /tmp/diskcheck_num_tmp
# 循环读取磁盘使用率,并进行判断
while [ "$read_num" -le $(wc -l < /tmp/diskcheck_num_tmp) ]
do
# 提取某一行的磁盘使用率
size=$(sed -n "$read_num"p /tmp/diskcheck_num_tmp)
# 判断磁盘使用率是否超过阈值
if [ "$size" -gt "$FSMAX" ]
then
# 如果超过阈值,则发送警报邮件(此处代码有误,稍后修正)
fi
# 提取对应的磁盘分区信息,并追加到邮件内容中(此处代码有误,稍后修正)
# ...(省略部分代码)
# 更新读取行数变量
read_num=$(expr $read_num + 1)
done
# 更新服务器IP地址的索引变量
ip_num=$(expr $ip_num + 1)
done
112 端口探测脚本
#!/bin/bash
HOST=$1
PORT="22 25 80 8080"
for PORT in $PORT; do
if echo &>/dev/null > /dev/tcp/$HOST/$PORT; then
echo "$PORT open"
else
echo "$PORT close"
fi
done
if echo &>/dev/null > /dev/tcp/ H O S T / HOST/ HOST/PORT; then … else … fi:使用Bash的内置TCP/IP功能尝试连接指定主机的端口。如果连接成功(即端口开放),则输出“PORTopen”,否则输出“PORT close”。
113 shell:将文件从当前服务器迁移到另一个服务器
#!/bin/bash
filename=$1
ip=192.168.1.202
passwd=1
expect <<EOF
spawn scp $filename root@$ip:/root
#expect "yes/no" {send "yes\n"}
expect "password" {send "$passwd\n"}
expect eof
EOF
114 kubernetes中的yaml配置文件保持
#/bin/bash
#
# K8S_YAML_SHELL_DIR:记录脚本和resources.txt存放位置,移动是需要修改其值
# 一键备份K8s集群YAML文件脚本
# resources.txt文件,编写需要备份资源
#
# 定时任务示例
# 0 0 */1 * * /usr/bin/bash /a/k8s-yaml-all-bak/start.sh > /a/k8s-yaml-all-bak/yaml_bak.logs 2>&1
# 后台运行示例
# nohup /usr/bin/bash /a/k8s-yaml-all-bak/start.sh > /a/k8s-yaml-all-bak/yaml_bak.logs 2>&1 &
# 当前时间
DATE=`date +%Y-%m-%d--%H-%M-%S`
# 备份路径
K8S_YAML_BACKUP_DIR="/opt/k8s_yaml_bak"
# 脚本存放目录
K8S_YAML_SHELL_DIR="/a/k8s-yaml-all-bak"
if [ ! -d $K8S_YAML_BACKUP_DIR ];then
mkdir -p $K8S_YAML_BACKUP_DIR
fi
# 获取备份资源
if [ -f ${K8S_YAML_SHELL_DIR}/resources.txt ];then
RESOURCES=`cat ${K8S_YAML_SHELL_DIR}/resources.txt`
# 判断资源文件是否为空
if [[ $RESOURCES == "" ]]; then
echo "${DATE} ${K8S_YAML_SHELL_DIR}/resources.txt 文件为空,请输入资源名称"
exit 1
fi
else
echo "resources.txt文件,不存在!"
exit 1
fi
# 每次备份单独创建一个家目录+时间
mkdir -p ${K8S_YAML_BACKUP_DIR}/k8s-${DATE}
# 获取家目录
GET_HOME_DIR=`ls -l ${K8S_YAML_BACKUP_DIR} | tail -n 1 | awk '{print $9}'`
echo "备份路径:$K8S_YAML_BACKUP_DIR/$GET_HOME_DIR"
# 获取k8s名称空间
NAMESPACE=`kubectl get ns | awk '{print $1}' | tail -n +2`
dump_yaml(){
# 遍历NS
for NS in $NAMESPACE ;do
# 创建NS备份目录
mkdir -p ${K8S_YAML_BACKUP_DIR}/${GET_HOME_DIR}/${NS}
# 过滤NS(kube-public、kube-system)
if [[ $NS != "kube-public" && $NS != "kube-system" && $NS != "default" && $NS != "velero" ]]; then
# 遍历k8s资源
for RESOURCE in $RESOURCES; do
# 创建资源目录
mkdir -p ${K8S_YAML_BACKUP_DIR}/${GET_HOME_DIR}/${NS}/${RESOURCE}
# 遍历对应资源名称
for RESOURCE_NAME in $(kubectl get $RESOURCE -n $NS | awk '{print $1}' | tail -n +2);do
DATE_YAML=`date +%Y-%m-%d--%H:%M:%S`
echo "${DATE_YAML} 导出YAML: ${NS} ${RESOURCE} ${RESOURCE_NAME} "
# 导出对应名称空间下对应资源的yaml
kubectl get ${RESOURCE} ${RESOURCE_NAME} -n ${NS} -o yaml > ${K8S_YAML_BACKUP_DIR}/${GET_HOME_DIR}/$NS/${RESOURCE}/${RESOURCE_NAME}.yaml
echo ""
done
done
fi
done
}
del_yaml(){
for DIR_NAME in $(find $K8S_YAML_BACKUP_DIR -type d -mtime +7);do
DATE_YAML=`date +%Y-%m-%d--%H:%M:%S`
echo "${DATE_YAML} 删除:$DIR_NAME" > ${K8S_YAML_SHELL_DIR}/del-yaml.logs
rm -rf $DIR_NAME >> ${K8S_YAML_SHELL_DIR}/del-yaml.logs
echo "" >> ${K8S_YAML_SHELL_DIR}/del-yaml.logs
done
}
dump_yaml
del_yaml
115 Shell脚本批量监控网站健康状态
#/bin/bash
check_url() {
HTTP_CODE=$(curl -o /dev/null --connect-timeout 3 -s -w "%{http_code}" $1)
if [ $HTTP_CODE -eq 200 ];then
echo "$URL Access successful"
continue
fi
}
URL_LIST="
www.baidu.com
www.qq.com
https://hao.360.com
"
for URL in $URL_LIST ; do
check_url $URL
check_url $URL
check_url $URL
echo "$URL Access failure!"
done
116、使用expect工具自动进行SSH连接,自动远程登陆,并发送命令
#!/bin/bash#!/bin/bash
# 接收所有传入的参数作为需要远程执行的命令
COMMAND=$*
# 主机信息文件,记录着每台主机的IP、用户名、端口和密码
HOST_INFO=host.info
# 遍历host.info文件中的每一行,提取IP地址
for IP in $(awk '/^[^#]/{print $1}' $HOST_INFO); do
# 根据IP地址从host.info文件中提取对应的用户名
USER=$(awk -v ip=$IP 'ip==$1{print $2}' $HOST_INFO)
# 根据IP地址从host.info文件中提取对应的端口号
PORT=$(awk -v ip=$IP 'ip==$1{print $3}' $HOST_INFO)
# 根据IP地址从host.info文件中提取对应的密码
PASS=$(awk -v ip=$IP 'ip==$1{print $4}' $HOST_INFO)
# 使用expect工具自动进行SSH连接,并发送命令
expect -c "
spawn ssh -p $PORT $USER@$IP ## spawn这个不是一个独立命令,而是 expect 工具中的一个关键字。expect 是一个用于自动化交互式应用程序(如 SSH、FTP、passwd 等)的工具。spawn 关键字用于启动一个新的进程,并与之交互。
expect {
\"(yes/no)\" {send \"yes\r\"; exp_continue}
\"password:\" {send \"$PASS\r\"; exp_continue}
\"$USER@*\" {send \"$COMMAND\r exit\r\"; exp_continue}
}
"
# 输出分隔线,方便查看每台主机的执行结果
echo "-------------------"
done
117、定时清理与统计日志文件的艺术
#!/bin/bash
################################################################
# 每小时执行一次脚本(任务计划),当时间为0点或12点时,将目标目录下的所有文件内容清空,
# 但不删除文件,其他时间则只统计各个文件的大小,一个文件一行,输出到以时间和日期命名的文件中,
# 需要考虑目标目录下二级、三级等子目录的文件
################################################################
# 定义日志文件,以小时和日期命名
logfile=/tmp/`date +%H-%F`.log
# 获取当前小时数
n=`date +%H`
# 判断当前时间是否为0点或12点
if [ $n -eq 00 ] || [ $n -eq 12 ]
then
# 如果是0点或12点,则遍历目标目录下的所有文件,并清空文件内容
for i in `find /data/log/ -type f`
do
true > $i
done
else
# 如果不是0点或12点,则遍历目标目录下的所有文件,并统计文件大小,输出到日志文件
for i in `find /data/log/ -type f`
do
du -sh $i >> $logfile
done
fi
#######################################################################
# 使用 chmod +x log_manage.sh 命令为脚本文件赋予执行权限。
# 使用 crontab -e 命令编辑 crontab 文件,添加一行定时任务:
## 每小时执行一次脚本
# 0 * * * * /path/to/log_manage.sh
### 每半个小时执行一次脚本
# 0,30 * * * * /path/to/log_manage.sh
########################################################################
118、查看所有用户的定时任务
sudo bash -c 'for user in $(cut -f1 -d: /etc/passwd); do echo "===== $user ====="; crontab -l -u $user 2>/dev/null; done'
119、自动备份脚本
- 这个脚本创建了重要目录的自动备份,确保数据始终受到保护。
#!/bin/bash
# 备份一个目录并将其存储在带有时间戳的备份文件夹中
SOURCE="/path/to/important/data"
DEST="/path/to/backup/location"
TIMESTAMP=$(date +"%Y%m%d%H%M%S")
tar -czvf "$DEST/backup_$TIMESTAMP.tar.gz" "$SOURCE"
echo "备份完成: $DEST/backup_$TIMESTAMP.tar.gz"
120、日志轮转
日志可能会变得很大并占用宝贵的磁盘空间。此脚本会循环并压缩日志文件。
#!/bin/bash
# 轮转并压缩日志
LOG_FILE="/path/to/logfile.log"
BACKUP_DIR="/path/to/log/backup"
TIMESTAMP=$(date +"%Y%m%d")
mv "$LOG_FILE" "$BACKUP_DIR/log_$TIMESTAMP.log"
gzip "$BACKUP_DIR/log_$TIMESTAMP.log"
touch "$LOG_FILE"
echo "日志轮转完成。"