搬砖 Shell 脚本整理

status
Published
type
Post
slug
some-shell-scripts-collect
date
Sep 25, 2020
tags
Tool
Shell
Linux
summary
这是一篇关于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 中的变量替换,详细可参见
主要为如下内容:
变量形式
作用说明
${变量#关键词} ${变量##关键词}
若变量内容从头开始的数据符合『关键词』,则将符合的最短数据删除 若变量内容从头开始的数据符合『关键词』,则将符合的最长数据删除
${变量%关键词} ${变量 %% 关键词}
若变量内容从尾向前的数据符合『关键词』,则将符合的最短数据删除 若变量内容从尾向前的数据符合『关键词』,则将符合的最长数据删除
${变量/旧字符串/新字符串} ${变量//旧字符串/新字符串}
若变量内容符合『旧字符串』则『第一个旧字符串会被新字符串取代』 若变量内容符合『旧字符串』则『全部的旧字符串会被新字符串取代』
 
  • 去除换行符
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