Linux 常用运维脚本

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,高可用系列 2核4GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 同步本机时间ntpdate 210.72.145.44

同步本机时间

ntpdate 210.72.145.44


清除系统缓存,空出更多内存

free && sync && echo 3 > /proc/sys/vm/drop_caches && free


杀掉僵尸进程

kill $(ps -A -ostat,ppid | awk '/[zZ]/ && !a[$2]++ {print $2}')


显示全部arp解析

tcpdump 'arp' -e -i eth0 -n -p -t |grep is-at

eth0对应要换成你的显步名称


监看本机网卡端口情况

tcpdump -n -vv tcp port $1 -i em1

em1为对应的网卡名称。


检查本机连接数

netstat -nat |awk '{print $6}'|sort|uniq -c|sort -nr


查看tomcat日志中的异常

tail -F /var/log/tomcat8/catalina.out |grep -E 'Exception|at' |grep -v WARN

这里tomcat8要对应成你的相应版本


删除5天以前的tomcat日志

sudo find /var/lib/tomcat8/logs/ -mtime +5 -exec rm {} \;


清空 memcache 缓存

以下存成脚本,

#!/bin/sh
#实现通过主机名,端口清相应的memcache缓存 
if(($#<2));then
    echo "usage:$0 host port";
    exit 1;
fi
#如果参数缺失,退出程序,返回状态1
exec 6<>/dev/tcp/$1/$2 2>/dev/null;
#打开host的port 可读写的socket连接,与文件描述符6连接
if(($?!=0));then
    echo "open $1 $2 error!";
    exit 1;
fi
#如果打开失败,$?返回不为0,终止程序
echo -e "flush_all">&6;
echo -e "quit">&6;
#将HEAD 信息,发送给socket连接
cat<&6;
#从socket读取返回信息,显示为标准输出
exec 6<&-;
exec 6>&-;
#关闭socket的输入,输出
exit 0;


修改VirtualBox虚拟机的内存分配

保存脚本,第一个参数为虚拟机的名称,第二个为内存大小,如2G

#!/bin/bash
VM=$1
VBoxManage controlvm $VM poweroff
VBoxManage modifyvm $VM  --memory $2
VBoxManage startvm $VM --type headless


为VirtualBox 虚拟机加磁盘

#!/bin/sh
#machine=phptest
machine=$1
VBoxManage controlvm "$machine" poweroff
disk=/home/xwx/VirtualBox\ VMs/$machine/${machine}_swap.vdi
#VBoxManage createhd --filename "$disk" --size 1024
#VBoxManage storageattach "$machine" --storagectl "IDE" --port 1 --type hdd --medium $disk
#VBoxManage storageattach "$machine" --storagectl SATA --port 1 --type hdd --medium $disk
VBoxManage storageattach "$machine" --storagectl "SATA 控制器" --port 1 --type hdd --medium "$disk"


修改克隆虚拟机的ip地址

虚拟机克隆之前,第一次启动时需要修改ip才能远程控制:

#!/bin/bash
# set modify
ip=/etc/network/interfaces
hn=/etc/hostname
netmask=255.255.255.0
network=192.168.20.0
broadcast=192.168.20.255
gateway=192.168.20.1
# mod ip、mask、gw、dns、hostname
cp $ip /etc/network/interfaces.bak
sed -ri 's/(iface eth0 inet).*/\iface eth0 inet static/' /etc/network/interfaces
echo "Please input IP:"
read ipadd
   if [ -n "$ipadd" ]; then
     echo "address $ipadd" >> $ip
     echo "Modify Completed "
   else
     echo "Not Modified"
   fi
echo "netmask $netmask" >> $ip
echo "Netmask Modify Completed "
echo "network $network" >> $ip
echo "Network Modify Completed "
echo "broadcast $broadcast" >> $ip
echo "Broadcast Modify Completed "
echo "gateway $gateway" >> $ip
echo "Gateway Modify Completed "
echo "Please input hostname:"
read hostname
if [ -n "$hostname" ]; then
   echo "$hostname" > $hn
   echo "Modify Completed "
else
   echo "Default Hostname"
fi
echo "All modification completion"
read -n1 -p "Whether restart network [Y/N]?"
case $REPLY in
Y|y) echo
       /etc/init.d/networking restart;;
N|n) echo
       echo "Network needs to restart to take effect!!!!!!";;
esac
exit


实时统计nginx日志

使用goaccess软件,可能用apt install goaccessyum install goaccess安装。

sudo goaccess /var/log/nginx/access.log --log-format='%h %^[%d:%t %^] "%r" %s %b "%R" "%u" "-" "%v"' --date-format='%d/%b/%Y' --time-format='%H:%M:%S'


备份nginx配置文件

nginx会频繁修改,改之前最好备份一下:

###################################################################
#######mysqldump###################################################
#!/bin/sh
# -----------------------------
# the directory for story your backup file.
backup_dir="/home/your/backup"
# date format for backup file (dd-mm-yyyy)
time="$(date +"%Y%m%d")"
MKDIR="$(which mkdir)"
RM="$(which rm)"
MV="$(which mv)"
TAR="$(which tar)"
GZIP="$(which gzip)"
#针对不同系统,如果环境变量都有。可以去掉
# check the directory for store backup is writeable
test ! -w $backup_dir && echo "Error: $backup_dir is un-writeable." && exit 0
# the directory for story the newest backup
test ! -d "$backup_dir" && $MKDIR "$backup_dir"
$TAR -zcPf $backup_dir/$HOSTNAME.nginx.$time.tar.gz  /etc/nginx
$TAR -zcPf $backup_dir/$HOSTNAME.cron_daily.$time.tar.gz  /etc/cron.daily
#delete the oldest backup 30 days ago
find $backup_dir -name "*.gz" -mtime +30 |xargs rm -rf
exit 0;


nginx 自动筛选出访问量过大的ip进行屏避

#!/bin/bash
nginx_home=/etc/nginx
log_path=/var/log/nginx
tail -n10000 $log_path/access.log \
      |awk '{print $1,$12}' \
      |grep -i -v -E "google|yahoo|baidu|msnbot|FeedSky|sogou" \
      | grep -v '223.223.198.231' \
      |awk '{print $1}'|sort|uniq -c|sort -rn \
      |awk '{if($1>50)print "deny "$2";"}' >>./blockips.conf
sort ./blockips.conf |uniq -u  >./blockips_new.conf
mv ./blockips.conf ./blockips_old.conf
mv ./blockips_new.conf ./blockips.conf
cat ./blockips.conf
#service nginx  reload


监控各网站首页

#!/bin/sh
RED='\033[0;31m'
GREEN='\033[0;32m'
NC='\033[0m' # No Color
function test_domain {
        local domain=$1
        status=`curl -s -o /dev/null -I -w "%{http_code}" $domain`
        if [ $status -eq '404' ]
        then
          printf "${domain}${RED}  ${status}${NC}\n"
        else
          printf "$domain$GREEN  $status$NC\n"
        fi
}
domain_list=$'bixuebihui.cn\nwww.bixuebihui.cn\ndev.bixuebihui.cn\nblog.bixuebihui.cn\nbixuebihui.com\nwww.bixuebihui.com'
while read -r domain; do
#       echo "... $domain ..."
   test_domain "http://$domain"
   test_domain "https://$domain"
done <<< "$domain_list"


从mysql日志里过滤慢sql

#!/usr/bin/perl
#
# Nathanial Hendler
# http://retards.org/
#
# 2001-06-26 v1.0
#
# This perl script parses a MySQL slow_queries log file
# ignoring all queries less than $min_time and prints
# out how many times a query was greater than $min_time
# with the seconds it took each time to run.  The queries
# are sorted by number of times it took; the most often
# query appearing at the bottom of the output.
#
# Usage: mysql_slow_log_parser logfile
#
# ------------------------
# SOMETHING TO THINK ABOUT (aka: how to read output)
# ------------------------
#
# Also, it does to regex substitutions to normalize
# the queries...
#
#   $query_string =~ s/\d+/XXX/g;
#   $query_string =~ s/([\'\"]).+?([\'\"])/$1XXX$2/g;
#
# These replace numbers with XXX and strings found in
# quotes with XXX so that the same select statement
# with different WHERE clauses will be considered
# as the same query.
#
# so these...
#
#   SELECT * FROM offices WHERE office_id = 3;
#   SELECT * FROM offices WHERE office_id = 19;
#
# become...
#
#   SELECT * FROM offices WHERE office_id = XXX;
#
#
# And these...
#
#   SELECT * FROM photos WHERE camera_model LIKE 'Nikon%';
#   SELECT * FROM photos WHERE camera_model LIKE '%Olympus';
#
# become...
#
#   SELECT * FROM photos WHERE camera_model LIKE 'XXX';
#
#
# ---------------------
# THIS MAY BE IMPORTANT (aka: Probably Not)
# ---------------------
#
# *SO* if you use numbers in your table names, or column
# names, you might get some oddities, but I doubt it.
# I mean, how different should the following queries be
# considered?
#
#   SELECT car1 FROM autos_10;
#   SELECT car54 FROM autos_11;
#
# I don't think so.
#
$min_time       = 0;    # Skip queries less than $min_time
$min_rows       = 0;
$max_display    = 10;   # Truncate display if more than $max_display occurances of a query
print "\n Starting... \n";
$query_string   = '';
$time           = 0;
$new_sql        = 0;
##############################################
# Loop Through The Logfile
##############################################
while (<>) {
        # Skip Bogus Lines
        next if ( m|/.*mysqld, Version:.+ started with:| );
        next if ( m|Tcp port: \d+  Unix socket: .*mysql.sock| );
        next if ( m|Time\s+Id\s+Command\s+Argument| );
        next if ( m|administrator\s+command:| );
        # print $_;
        # if ( /Query_time:\s+(.*)\s+Lock_time:\s+(.*)\s/ ) {
        #if ( /Query_time:\s+(.*)\s+Lock_time:\s+(.*)\s+Rows_examined:\s+(\d+)/ ) {
        if ( /Query_time:\s+(.*)\s+Lock_time:\s+(.*)\s+Rows_examined:\s+(.*)/ ) {
                $time    = $1;
                $rows    = $3;
                $new_sql = 1;
                # print "found $1 $3\n";
                next;
        }
        if ( /^\#/ && $query_string ) {
                        if (($time > $min_time) && ($rows >= $min_rows)) {
                                $orig_query = $query_string;
                                $query_string =~ s/\d+/XXX/g;
                                $query_string =~ s/'([^'\\]*(\\.[^'\\]*)*)'/'XXX'/g;
                                $query_string =~ s/"([^"\\]*(\\.[^"\\]*)*)"/"XXX"/g;
                                #$query_string =~ s/([\'\"]).+?([\'\"])/$1XXX$2/g;
                                #$query_string =~ s/\s+/ /g;
                                #$query_string =~ s/\n+/\n/g;
                                push @{$queries{$query_string}}, $time;
                                push @{$queries_rows{$query_string}}, $rows;
                                $queries_tot{$query_string} += $time;
                                $queries_orig{$query_string} = $orig_query;
                                $query_string = '';
                        }
        } else {
                if ($new_sql) {
                        $query_string = $_;
                        $new_sql = 0;
                } else {
                        $query_string .= $_;
                }
        }
}
##############################################
# Display Output
##############################################
foreach my $query ( sort { $queries_tot{$b} <=> $queries_tot{$a} } keys %queries_tot )  {
        my $total = 0;
        my $cnt = 0;
        my @seconds = sort { $a <=> $b } @{$queries{$query}};
        my @rows    = sort { $a <=> $b } @{$queries_rows{$query}};
        ($total+=$_) for @seconds;
        ($cnt++) for @seconds;
        print "### " . @{$queries{$query}} . " Quer" . ((@{$queries{$query}} > 1)?"ies ":"y ") . "\n";
        print "### Total time: " . $total .", Average time: ".($total/$cnt)."\n";
        print "### Taking ";
        print @seconds > $max_display ? "$seconds[0] to $seconds[-1]" : sec_joiner(\@seconds);
        print " seconds to complete\n";
        print "### Rows analyzed ";
        print @rows > $max_display ? "$rows[0] - $rows[-1]": sec_joiner(\@rows);
        print "\n";
        print "$query\n";
        print $queries_orig{$query}."\n\n";
}
sub sec_joiner {
        my ($seconds) = @_;
        $string = join(", ", @{$seconds});
        $string =~ s/, (\d+)$/ and $1/;
        return $string;
}
exit(0);


本机路由表

ip route add 5.6.13.192/26 dev em1 src 5.6.13.218 table 10
ip route add default via 5.6.13.254 table 10
ip route add 5.6.13.192/26 dev em2 src 5.6.13.217 table 20
ip route add default via 5.6.13.254 table 20
ip route add 5.6.13.192/26 dev em1 src 5.6.13.218
ip route add 5.6.13.192/26 dev em2 src 5.6.13.217
ip route add default via 5.6.13.254
ip rule add from 5.6.13.218 table 10
ip rule add from 5.6.13.217 table 20
ip route flush cache


出现异常时,用钉钉dingtalk报警

#!/bin/python
# -*- coding: utf-8 -*-
from flask import Flask
from flask import request
import json
import requests
app = Flask(__name__)
def transform(text):
    textMap = json.loads(text)
    nodePorturl = 'http://192.168.10.182:3672'
    externalURL = textMap['externalURL']
    print(externalURL)
    links =[]
    for alert in textMap['alerts']:
        print('-------------')
        time = alert['startsAt'] + ' -- ' + alert['endsAt']
        generatorURL = alert['generatorURL'];
        generatorURL = nodePorturl+generatorURL[generatorURL.index('graph'):]
        summary = alert['annotations']['summary']
        description = alert['annotations']['description']
        status = alert['status']
        title = alert['labels']['alertname']
相关文章
|
22天前
|
存储 安全 Unix
七、Linux Shell 与脚本基础
别再一遍遍地敲重复的命令了,把它们写进Shell脚本,就能一键搞定。脚本本质上就是个存着一堆命令的文本文件,但要让它“活”起来,有几个关键点:文件开头最好用#!/usr/bin/env bash来指定解释器,并用chmod +x给它执行权限。执行时也有讲究:./script.sh是在一个新“房间”(子Shell)里跑,不影响你;而source script.sh是在当前“房间”里跑,适合用来加载环境变量和配置文件。
273 9
|
Ubuntu Linux 网络安全
Linux系统初始化脚本
一款支持Rocky、CentOS、Ubuntu、Debian、openEuler等主流Linux发行版的系统初始化Shell脚本,涵盖网络配置、主机名设置、镜像源更换、安全加固等多项功能,适配单/双网卡环境,支持UEFI引导,提供多版本下载与持续更新。
140 0
Linux系统初始化脚本
|
22天前
|
存储 Shell Linux
八、Linux Shell 脚本:变量与字符串
Shell脚本里的变量就像一个个贴着标签的“箱子”。装东西(赋值)时,=两边千万不能有空格。用单引号''装进去的东西会原封不动,用双引号""则会让里面的$变量先“变身”再装箱。默认箱子只能在当前“房间”(Shell进程)用,想让隔壁房间(子进程)也能看到,就得给箱子盖个export的“出口”戳。此外,Shell还自带了$?(上条命令的成绩单)和$1(别人递进来的第一个包裹)等许多特殊箱子,非常有用。
114 2
|
3月前
|
Web App开发 缓存 安全
Linux一键清理系统垃圾:释放30GB空间的Shell脚本实战​
这篇博客介绍了一个实用的Linux系统盘清理脚本,主要功能包括: 安全权限检查和旧内核清理,保留当前使用内核 7天以上日志文件清理和系统日志压缩 浏览器缓存(Chrome/Firefox)、APT缓存、临时文件清理 智能清理Snap旧版本和Docker无用数据 提供磁盘空间使用前后对比和大文件查找功能 脚本采用交互式设计确保安全性,适合定期维护开发环境、服务器和个人电脑。文章详细解析了脚本的关键功能代码,并给出了使用建议。完整脚本已开源,用户可根据需求自定义调整清理策略。
318 1
|
5月前
|
Java Linux
自定义linux脚本用于快速jar包启动、停止、重启
自定义linux脚本用于快速jar包启动、停止、重启
284 29
|
5月前
|
Linux Shell
Centos或Linux编写一键式Shell脚本删除用户、组指导手册
Centos或Linux编写一键式Shell脚本删除用户、组指导手册
142 4
|
5月前
|
Linux Shell 数据安全/隐私保护
Centos或Linux编写一键式Shell脚本创建用户、组、目录分配权限指导手册
Centos或Linux编写一键式Shell脚本创建用户、组、目录分配权限指导手册
309 3
|
6月前
|
Linux Shell
在Linux、CentOS7中设置shell脚本开机自启动服务
以上就是在CentOS 7中设置shell脚本开机自启动服务的全部步骤。希望这个指南能帮助你更好地管理你的Linux系统。
490 25
|
6月前
|
安全 Linux
阿里云linux服务器使用脚本通过安全组屏蔽异常海外访问ip
公网网站可能会遭受黑客攻击导致访问异常,使用此脚本可以屏蔽掉异常IP 恢复访问。也可自行设置定时任务定期检测屏蔽。
488 28
|
6月前
|
运维 安全 Linux
试试Linux设备命令行运维工具——Wowkey
WowKey 是一款专为 Linux 设备设计的命令行运维工具,提供自动化、批量化、标准化、简单化的运维解决方案。它简单易用、高效集成且无依赖,仅需 WIS 指令剧本文件、APT 账号密码文件和 wowkey 命令即可操作。通过分离鉴权内容与执行内容,WowKey 让运维人员专注于决策,摆脱繁琐的交互与执行细节工作,大幅提升运维效率与质量。无论是健康检查、数据采集还是配置更新,WowKey 都能助您轻松应对大规模设备运维挑战。立即从官方资源了解更多信息:https://atsight.top/training。
下一篇
oss教程