搬砖 Shell 脚本整理
✨ 这是一篇关于Shell脚本的整理文章,其中包括了一些实用的Shell脚本和命令组合,以及它们的用法和作用说明。文章内容涵盖了删除备份文件、批量重命名文件、变量替换、去除换行符、统计匹配行数、分析Nginx日志、DDoS攻击防范、解压缩脚本、Git修改历史commit信息、以及一些网络连接和Docker容器日志的清空操作。
此处整理收集一些会用到的 Shell 脚本/命令组合,方便查阅
- 删除n天前的备份文件
# 删除7天前备份文件!
find ${dir_path:=/data/back_data/} -name '*.tar.gz' -type f -mtime +7 |xargs rm -rf- 批量重命名文件
# 去除所有文件名中lalala
for fname in $(ls *lalala.jpg); do
mv $fname $(echo ${fname//lalala/})
done此处使用了 Shell 中的变量替换,详细可参见
http://cn.linux.vbird.org/linux_basic/0320bash_2.php#variable_other主要为如下内容:
| 变量形式 | 作用说明 |
| ${变量#关键词} ${变量##关键词} | 若变量内容从头开始的数据符合『关键词』,则将符合的最短数据删除 若变量内容从头开始的数据符合『关键词』,则将符合的最长数据删除 |
| ${变量%关键词} ${变量 %% 关键词} | 若变量内容从尾向前的数据符合『关键词』,则将符合的最短数据删除 若变量内容从尾向前的数据符合『关键词』,则将符合的最长数据删除 |
| ${变量/旧字符串/新字符串} ${变量//旧字符串/新字符串} | 若变量内容符合『旧字符串』则『第一个旧字符串会被新字符串取代』 若变量内容符合『旧字符串』则『全部的旧字符串会被新字符串取代』 |
- 去除换行符
sed -i ':a;N;$!ba;s/\n/ /g'- 统计匹配行数
ps -ef | grep java | wc -l
# 或者 grep -c
ps -ef | grep -c java- 分析 Nginx 日志,统计同一IP访问次数并排序
# 使用`awk`命令对输入的每一行进行处理。`{d[$1]++}`表示以每行的第一个字段(IP地址)作为索引,将该字段的值作为数组`d`的键,并将该键对应的值加1。`END {for (i in d) print d[i],i}`表示在处理完所有行后,遍历数组`d`中的键值对,并按照格式输出键值对,即IP地址和出现次数。
cat access.log | awk '{d[$1]++} END {for (i in d) print d[i],i}' | sort -nr | head#!/bin/bash
# 日志格式: $remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" "$http_x_forwarded_for"
LOG_FILE=$1
echo "统计访问最多的10个IP"
awk '{a[$1]++}END{print "UV:",length(a);for(v in a)print v,a[v]}' $LOG_FILE |sort -k2 -nr |head -10
echo "----------------------"
echo "统计时间段访问最多的IP"
awk '$4>="[01/Dec/2018:13:20:25" && $4<="[27/Nov/2018:16:20:49"{a[$1]++}END{for(v in a)print v,a[v]}' $LOG_FILE |sort -k2 -nr|head -10
echo "----------------------"
echo "统计访问最多的10个页面"
awk '{a[$7]++}END{print "PV:",length(a);for(v in a){if(a[v]>10)print v,a[v]}}' $LOG_FILE |sort -k2 -nr
echo "----------------------"
echo "统计访问页面状态码数量"
awk '{a[$7" "$9]++}END{for(v in a){if(a[v]>5)print v,a[v]}}'- DDoS 攻击防范(自动封禁IP)
#!/bin/bash
DATE=$(date +%d/%b/%Y:%H:%M)
LOG_FILE=/usr/local/nginx/logs/test.access.log
ABNORMAL_IP=$(tail -n5000 $LOG_FILE |grep $DATE |awk '{a[$1]++}END{for(i in a)if(a[i]>10)print i}')
for IP in $ABNORMAL_IP; do
if [ $(iptables -vnL |grep -c "$IP") -eq 0 ]; then
iptables -I INPUT -s $IP -j DROP
echo "$(date +'%F_%T') $IP" >> /tmp/drop_ip.log
fi
done- ssh_config 配置
Host *
StrictHostKeyChecking no
UserKnownHostsFile=/dev/null
ForwardAgent yes
ServerAliveInterval 10
ServerAliveCountMax 10000
TCPKeepAlive no
ControlMaster auto
ControlPath ~/.ssh/session/%h-%p-%r
ControlPersist 12h
Host server
Hostname 192.168.0.1
Port 22
User root
IdentityFile ~/.ssh/id_rsa- 解压缩脚本
#!/bin/bash
# function Extract for common file formats
function extract {
if [ -z "$1" ]; then
# display usage if no parameters given
echo "Usage: extract <path/file_name>.<zip|rar|bz2|gz|tar|tbz2|tgz|Z|7z|xz|ex|tar.bz2|tar.gz|tar.xz>"
else
if [ -f "$1" ] ; then
NAME=${1%.*}
#mkdir $NAME && cd $NAME
case "$1" in
*.tar.bz2) tar xvjf ./"$1" ;;
*.tar.gz) tar xvzf ./"$1" ;;
*.tar.xz) tar xvJf ./"$1" ;;
*.lzma) unlzma ./"$1" ;;
*.bz2) bunzip2 ./"$1" ;;
*.rar) unrar x -ad ./"$1" ;;
*.gz) gunzip ./"$1" ;;
*.tar) tar xvf ./"$1" ;;
*.tbz2) tar xvjf ./"$1" ;;
*.tgz) tar xvzf ./"$1" ;;
*.zip) unzip ./"$1" ;;
*.Z) uncompress ./"$1" ;;
*.7z) 7z x ./"$1" ;;
*.xz) unxz ./"$1" ;;
*.exe) cabextract ./"$1" ;;
*) echo "extract: '$1' - unknown archive method" ;;
esac
else
echo "'$1' - file does not exist"
fi
fi
}- Git 修改历史commit信息
git filter-branch --commit-filter '
if [ "$GIT_COMMITTER_EMAIL" = "a@example.com" ];
then
GIT_COMMITTER_NAME="Test";
GIT_AUTHOR_NAME="Test";
GIT_COMMITTER_EMAIL="b@example.com";
GIT_AUTHOR_EMAIL="b@example.com";
git commit-tree "$@";
else
git commit-tree "$@";
fi'
HEAD- 查找请求数前20个IP(请求来源):
netstat -anlp|grep 80|grep tcp|awk '{print $5}'|awk -F: '{print $1}'|sort|uniq -c|sort -nr|head -n20
netstat -ant |awk '/:80/{split($5,ip,”:”);++A[ip[1]]}END{for(i in A) print A[i],i}' |sort -rn|head -n20- 查找较多time_wait连接
netstat -n|grep TIME_WAIT|awk '{print $5}'|sort|uniq -c|sort -rn|head -n20- 找查较多的SYN连接
netstat -an | grep SYN | awk '{print $5}' | awk -F: '{print $1}' | sort | uniq -c | sort -nr | more- 根据端口列进程
netstat -ntlp | grep 80 | awk '{print $7}' | cut -d/ -f1- 清空 Docker 容器日志
#!/bin/bash
# 治标
logs=$(find /var/lib/docker/containers/ -name *-json.log)
for log in $logs
do
echo "clean logs : $log"
cat /dev/null > $log
done - 查看占用内存最高的进程 — topmem
alias topmem='ps aux --sort=-%mem | awk '\\''NR==1 {printf "%-10s %-6s %s %s %s\\n", $2, $4, "MEM", $11, $12; next} {printf "%-10s %-6s %.2fMB %s %s\\n", $2, $4, $6/1024, $11, substr($12,1,20)}'\\'' | head -n 30'