Liunx常用脚本案例


Nginx部署脚本
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#!/bin/bash

# 安装编译Nginx所需的依赖库
apt-get update
apt-get install -y build-essential zlib1g-dev libpcre3-dev libssl-dev

# 下载或指定Nginx源码包,并解压缩
NGINX_SOURCE_URL="http://nginx.org/download/nginx-1.22.0.tar.gz"
NGINX_SOURCE_FILE="/tmp/nginx-1.22.0.tar.gz" #指定本地路径

# 下载Nginx源码包
wget $NGINX_SOURCE_URL -O $NGINX_SOURCE_FILE

# 解压缩Nginx源码包
tar -xzvf $NGINX_SOURCE_FILE
cd nginx-1.22.0

# 编译安装Nginx
./configure
make
make install

# 启动Nginx服务
nginx

# 确认Nginx服务是否成功启动
ps aux | grep nginx

echo "Nginx安装和启动完成!"
Nginx平滑升级,检测现版本模块信息
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#!/bin/bash

# 获取当前运行的Nginx进程ID
NGINX_PID=$(pidof nginx)

# 检查Nginx进程是否存在
if [ -z "$NGINX_PID" ]; then
echo "Nginx is not running."
exit 1
fi

# 获取当前运行的Nginx进程的配置信息
NGINX_CONF=$(ps -p $NGINX_PID -o args= | awk '{print $NF}' | grep -E "^/.*nginx.conf$")

# 检查Nginx配置文件是否存在
if [ -z "$NGINX_CONF" ]; then
echo "Unable to determine Nginx configuration file."
exit 1
fi

# 获取Nginx模块信息
NGINX_MODULES=$(nginx -V 2>&1 | grep -oP -- '--with-[a-zA-Z\_-]+' | sed 's/--with-//')
echo "Current Nginx modules:"
echo "$NGINX_MODULES"
echo ""

# 下载或指定新版本的Nginx源码包,并解压缩
NGINX_SOURCE_URL="http://nginx.org/download/nginx-1.22.0.tar.gz"
NGINX_SOURCE_FILE="/tmp/nginx-1.22.0.tar.gz" #指定本地路径

# 下载Nginx源码包
wget "$NGINX_SOURCE_URL" -O "$NGINX_SOURCE_FILE"

# 解压缩Nginx源码包
tar -xzvf "$NGINX_SOURCE_FILE"
cd nginx-1.22.0

# 配置新版本的Nginx,保留原有模块配置
./configure --with-modules="$NGINX_MODULES"

# 编译新版本的Nginx
make

# 备份旧版本的Nginx可执行文件
mv /usr/sbin/nginx /usr/sbin/nginx.old

# 将新编译的Nginx可执行文件替换旧版本
mv objs/nginx /usr/sbin/nginx

# 启动新版本的Nginx
nginx -t && nginx -s reload

echo "Nginx平滑升级完成!"
Nginx的日志文件清理

保留最近15天内的日志文件,其他旧日志文件将被删除:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#!/bin/bash

log_dir="/var/log/nginx" # Nginx日志目录
days_to_keep=15 # 保留的天数

# 获取当前日期15天前的时间戳
timestamp=$(date -d "$days_to_keep days ago" +%s)

# 查找Nginx日志目录下的文件
for file in $log_dir/*.log; do

# 获取文件的最后修改时间
last_modified=$(stat -c %Y "$file")

# 检查文件最后修改时间是否早于15天前的时间戳
if ((last_modified < timestamp)); then
echo "删除旧日志文件: $file"
rm "$file"
fi
done

log_dir变量设置为Nginx日志文件所在的目录

days_to_keep变量指定了要保留的天数。

脚本保存为nginx_log_cleanup.sh文件,并为其赋予执行权限(例如:chmod +x nginx_log_cleanup.sh

Nginx访问访问日志按天切割
1
2
3
4
5
6
7
8
9
10
#!/bin/bash
LOG_DIR=/usr/local/nginx/logs
YESTERDAY_TIME=$(date -d "yesterday" +%F)
LOG_MONTH_DIR=$LOG_DIR/$(date +"%Y-%m")
LOG_FILE_LIST="default.access.log"

for LOG_FILE in $LOG_FILE_LIST; do
[ ! -d $LOG_MONTH_DIR ] && mkdir -p $LOG_MONTH_DIR
mv $LOG_DIR/$LOG_FILE $LOG_MONTH_DIR/${LOG_FILE}_${YESTERDAY_TIME}
done
Nginx访问日志分析脚本
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/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]}}'
系统配置初始化脚本
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#/bin/bash
# 设置时区并同步时间**
ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
if ! crontab -l |grep ntpdate &>/dev/null ; then
(echo "* 1 * * * ntpdate time.windows.com >/dev/null 2>&1";crontab -l) |crontab
fi

# 禁用selinux
sed -i '/SELINUX/{s/permissive/disabled/}' /etc/selinux/config

# 关闭防火墙
if egrep "7.[0-9]" /etc/redhat-release &>/dev/null; then
systemctl stop firewalld
systemctl disable firewalld
elif egrep "6.[0-9]" /etc/redhat-release &>/dev/null; then
service iptables stop
chkconfig iptables off
fi

# 历史命令显示操作时间
if ! grep HISTTIMEFORMAT /etc/bashrc; then
echo 'export HISTTIMEFORMAT="%F %T `whoami` "' >> /etc/bashrc
fi

# SSH超时时间
if ! grep "TMOUT=600" /etc/profile &>/dev/null; then
echo "export TMOUT=600" >> /etc/profile
fi

# 禁止root远程登录
sed -i 's/#PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config

# 禁止定时任务向发送邮件
sed -i 's/^MAILTO=root/MAILTO=""/' /etc/crontab

# 设置最大打开文件数
if ! grep "* soft nofile 65535" /etc/security/limits.conf &>/dev/null; then
cat >> /etc/security/limits.conf << EOF
* soft nofile 65535
* hard nofile 65535
EOF
fi

# 系统内核优化
cat >> /etc/sysctl.conf << EOF
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_tw_buckets = 20480
net.ipv4.tcp_max_syn_backlog = 20480
net.core.netdev_max_backlog = 262144
net.ipv4.tcp_fin_timeout = 20
EOF

# 减少SWAP使用
echo "0" > /proc/sys/vm/swappiness

# 安装系统性能分析工具及其他
yum install gcc make autoconf vim sysstat net-tools iostat if
巡检服务器磁盘利用率并判断是否超过80%阈值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#!/bin/bash

HOST_INFO=host.info #需巡检主机,按需设置路径
REPORT_FILE=report.txt #报告文件,按需设置路径
DAYS_TO_KEEP=15 #报告文件保存有效期

for IP in $(awk '/^[^#]/{print $1}' $HOST_INFO); do
USER=$(awk -v ip=$IP 'ip==$1{print $2}' $HOST_INFO)
PORT=$(awk -v ip=$IP 'ip==$1{print $3}' $HOST_INFO)
TMP_FILE=/tmp/disk.tmp

# SSH 连接到远程主机,获取磁盘使用情况信息
ssh -p $PORT $USER@$IP 'df -h' > $TMP_FILE

# 检查磁盘使用率是否超过阈值,输出警告信息
USE_RATE_LIST=$(awk 'BEGIN{OFS="="}/^\/dev/{print $NF,int($5)}' $TMP_FILE)
for USE_RATE in $USE_RATE_LIST; do
PART_NAME=${USE_RATE%=*}
USE_RATE=${USE_RATE#*=}
if [ $USE_RATE -ge 80 ]; then
echo "Warning: $PART_NAME Partition usage $USE_RATE%!" >> $REPORT_FILE
fi
done
done

# 清理旧的报告文件
find . -name $REPORT_FILE -mtime +$DAYS_TO_KEEP -delete

host.info文件的格式:IP_ADDRESS:主机的IP地址或主机名,USERNAME:SSH登录主机所使用的用户名,PORT:SSH端口号。

1
IP_ADDRESS USERNAME PORT
巡检脚本
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#!/bin/bash

#脚本功能描述:监控服务器主要性能参数指标
#监控项目:内核信息,主机名称,IP地址,登录账户,内存与swap信息,磁盘信息,CPU负载
#内核信息
kernel=$(uname -r)

#操作系统版本
release=$(cat /etc/redhat-release)

#主机名称
hostname=$HOSTNAME

#本地IP地址列表
localip=$(ip a s | awk '/inet /{print $2}')

#总内存容量
mem_total=$(free | awk '/Mem/{print $2}')

#剩余内存容量
mem_free=$(free | awk '/Mem/{print $NF}')

#总swap容量
swap_total=$(free | awk '/Swap/{print $2}')

#剩余swap容量
swap_free=$(free | awk '/Swap/{print $NF}')

#磁盘信息
disk=$(df | awk '/^\/dev/{print $1,$2,$4}'|column -t)

#CPU最近1分钟的平均负载
load1=$(uptime | sed 's/,//g' | awk '{print $(NF-2)}')

#CPU最近5分钟的平均负载
load5=$(uptime | sed 's/,//g' | awk '{print $(NF-1)}')

#CPU最近15分钟的平均负载
load15=$(uptime | sed 's/,//g' | awk '{print $(NF)}')

#登录用户数量
login_users=$(who | wc -l)

#进程数量
procs=$(ps aux | wc -l)

#系统总账户数量
users=$(sed -n '$=' /etc/passwd)

#CPU型号
cpu_info=$(LANG=C lscpu |awk -F: '/Model name/ {print $2}')

#CPU内核数量
cpu_core=$(awk '/processor/{core++} END{print core}' /proc/cpuinfo)

#安装性能监控软件
yum -y -q install sysstat &>/dev/null

echo -e "\033[34m提取磁盘性能指标,请稍后...\033[0m"

tps=$(LANG=C sar -d -p 1 6 | awk '/Average/' | tail -n +2 |awk '{print "["$2"]磁盘平均IO数量:"$3}') &

read_write=$(LANG=C sar -d -p 1 6 |awk '/Average/' | tail -n +2 | awk '{print "["$2"]平均每秒读写扇区量:"$4,$5}') &

#中断数量
irq=$(vmstat 1 2 |tail -n +4 | awk '{print $11}')

#上下文切换数量
cs=$(vmstat 1 2|tail -n +4 | awk '{print $12}')

#占用内存资源最多的10个进程列表
top_proc_mem=$(ps --no-headers -eo comm,rss | sort -k2 -n |tail -10)

#占用内存资源最多的10个进程列表
top_proc_cpu=$(ps --no-headers -eo comm,rss | sort -k2 -n |tail -10)

#获取网卡流量信息,接收|发送的数据流量,单位为字节(bytes)
net_monitor=$(cat /proc/net/dev | tail -n +3 |awk 'BEGIN{ print "网卡名称 入站数据流量(bytes) 出站数据流量(bytes)"} {print $1,$2,$10}' | column -t)

#输出数据信息
echo -e "\033[32m************************本机主要参数列表********************\033[0m"
echo -e "本机IP地址列表:\033[32m$localip\033[0m"
echo -e "本机主机名称:\033[32m$hostname\033[0m"
echo -e "操作系统版本为:\033[32m$release\033[0m,内核版本:\033[32m$kernel\033[0m"
echo -e "CPU型号为:\033[32m$cpu_info\033[0m,CPU内核数量:\033[32$kernel\033[0m"
echo -e "本机总内存容量:\033[32m$mem_total\033[0m,剩余可用内存容量:\033[32m$mem_free\033[0m"
echo -e "本机swap总容量:\033[32m$swap_local\033[0m,剩余swap容量:\033[32m$swap_free\033[0m"
echo -e "CPU最近1分钟,5分钟,15分钟的平均负载分别为:\033[32m$load1 $load5 $load15\033[0m"
echo -e "本机总账户数量为:\033[32m$users\033[0m,当前登录系统的账户数量:\033[32m$login_users\033[0m"
echo -e "当前系统中启动的进程数量:\033[32m$procs\033[0m"
echo -e "占用CPU资源最多的10个进程列表为:"
echo -e "\033[32m$top_proc_cpu\033[0m"
echo -e "占用CPU内存资源最多的10个进程列表为:"
echo -e "\033[32m$top_proc_mem\033[0m"
echo -e "CPU中断数量为:\033[32m$irq\033[0m,CPU上下文切换数量:\033[32m$cs\033[0m"
echo -e "每个磁盘分区的总容量与剩余容量信息如下:"
echo -e "$disk"
echo -e "$tps"
echo -e "$read_write"
echo -e "$net_monitor"
echo -e "\033[32m************************巡检结束********************\033[0m"
单节点Redis部署脚本

需要确保已经安装了 tcl插件包

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#!/bin/bash

```
PACKAGE_DIR=$1 #Redis安装包所在路径
#*.tar.gz software path
INSTALL_DIR=$2 #Redis安装路径
PASSWD=$3 #Redis密码
```

#获取redis版本
#带后缀的文件名 redis_filename_tmp=${PACKAGE_DIR##*/} #不带后缀的文件名 redis_filename=${redis_filename_tmp%.*.*}

if [ $# -lt 3 ]; then
echo "Usage: $0 PackageDir InstallDir PassWd"
echo "For example: $0 /tmp/redis-2.8.7.tar.gz /app/redis ccssoft"
echo "PackageDir:为redis安装包所在路径,本程序限定redis安装包为redis-x.x.x.tar.gz!" echo "InstallDir:为redis安装路径!"
echo "PassWd:为redis密码!"
exit 1;

fi

echo "你输入的安装包所在路径为: $PACKAGE_DIR" echo "你输入的安装路径为: $INSTALL_DIR" echo "你输入的密码: $PASSWD"
echo "你输入的redis版本为: $redis_filename"

#判断tcl插件是否存在,不存在则退出 if ! rpm -qa | grep tcl ;then

echo "ERROR:系统不存在tcl包,请安装后再运行此安装程序! 请使用root账号执行: yum -y install tcl"

exit 1 fi

#判断安装包是否存在,不存在则退出
if [ ! -f "$PACKAGE_DIR" ];then

```
echo "ERROR: $PACKAGE_DIR not exist!"
```

exit 1 fi

#判断安装路径是否存在,如果不存在则创建 if [ ! -d "$INSTALL_DIR" ]; then

```
echo "INFO:$INSTALL_DIR not exist!"
echo "mkdir -p $INSTALL_DIR"
mkdir -p $INSTALL_DIR/tmp
echo "INFO:$INSTALL_DIR creat successful!"
```

fi

#解压redis文件
tar -xvzf $PACKAGE_DIR -C $INSTALL_DIR/tmp
cd $INSTALL_DIR/tmp/$redis_filename
cp $INSTALL_DIR/tmp/$redis_filename/redis.conf $INSTALL_DIR/

#修改redis.conf
echo "requirepass $PASSWD" >> $INSTALL_DIR/redis.conf echo "masterauth $PASSWD" >> $INSTALL_DIR/redis.conf

#修改绑定ip地址
sed -i 's/bind 127.0.0.1/bind 0.0.0.0/g' $INSTALL_DIR/redis.conf

#编译安装
make && make test
echo -e "如果没有提示:""\033[32m All tests passed without errors! \033[0m 说明编译过 程中出现了错误,如果报错请手工处理后重新执行,请按任意键继续或按CTRL+C退出安装...."
read ANSWER
make PREFIX=$INSTALL_DIR install

#删除临时文件
rm -rf $INSTALL_DIR/tmp

#添加环境变量至当前用户.bash_profile
echo "export REDIS_HOME=$INSTALL_DIR" >> ~/.bash_profile
echo "export PATH=\$PATH:\$REDIS_HOME/bin:" >> ~/.bash_profile source ~/.bash_profile
echo "环境变量REDIS_HOME为:$REDIS_HOME"

#redis安装信息打印
echo "#!/bin/sh" > $INSTALL_DIR/info.sh
echo "#!/bin/sh" > $INSTALL_DIR/start.sh
echo "#!/bin/sh" > $INSTALL_DIR/stop.sh
echo "#!/bin/sh" > $INSTALL_DIR/restart.sh
echo "" >> $INSTALL_DIR/info.sh
echo "" >> $INSTALL_DIR/start.sh
echo "" >> $INSTALL_DIR/stop.sh
echo "" >> $INSTALL_DIR/restart.sh
echo "source ~/.bash_profile" >> $INSTALL_DIR/info.sh
echo "source ~/.bash_profile" >> $INSTALL_DIR/start.sh
echo "source ~/.bash_profile" >> $INSTALL_DIR/stop.sh
echo "source ~/.bash_profile" >> $INSTALL_DIR/restart.sh
echo "Redis服务启动 $INSTALL_DIR/start.sh "
echo "echo \"Redis服务启动 $INSTALL_DIR/start.sh \"" >> $INSTALL_DIR/info.sh echo "Redis服务停止 $INSTALL_DIR/stop.sh"
echo "echo \"Redis服务停止 $INSTALL_DIR/stop.sh \"" >> $INSTALL_DIR/info.sh
echo "Redis服务重启 $INSTALL_DIR/restart.sh"
echo "echo \"Redis服务重启 $INSTALL_DIR/restart.sh \"" >> $INSTALL_DIR/info.sh #初始化start.sh
echo "nohup $INSTALL_DIR/bin/redis-server $INSTALL_DIR/redis.conf > $INSTALL_DIR/redis.log &" >> $INSTALL_DIR/start.sh
echo "echo \" \"" >> $INSTALL_DIR/start.sh
echo "tail -f $INSTALL_DIR/redis.log" >> $INSTALL_DIR/start.sh
#初始化stop.sh
echo "ps -ef|grep redis | grep -v grep | awk '{print \$2}' | xargs kill -9 " >> $INSTALL_DIR/stop.sh

#初始化restart.sh
echo "ps -ef|grep redis | grep -v grep | awk '{print \$2}' | xargs kill -9 " >> $INSTALL_DIR/restart.sh
echo "$INSTALL_DIR/bin/redis-server $INSTALL_DIR/redis.conf" >> $INSTALL_DIR/restart.sh
echo "echo \" \"" >> $INSTALL_DIR/restart.sh
echo "tail -f $INSTALL_DIR/redis.log" >> $INSTALL_DIR/restart.sh

echo "INFO:redis软件安装完毕,安装信息 $INSTALL_DIR/info.sh!"
chmod 775 $INSTALL_DIR/*.sh

exit 0;
预防keepalive脑裂,VIP是否漂移到备份主机

脚本需要在备份主机上执行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#!/bin/bash

# 检测 VIP 是否已漂移到本地主机

function check_vip_status() {
VIP="192.168.0.100" # 替换为实际的 VIP 地址
IFACE="eth0" # 替换为实际的网络接口名称

ip addr show dev $IFACE | grep -q $VIP
if [ $? -eq 0 ]; then
echo "VIP $VIP is active on this host."
else
echo "VIP $VIP is not active on this host!"
# 在此处执行相应的操作,例如禁用 Keepalived
# systemctl stop keepalived
fi
}

# 定期检测 VIP 状态

while true; do
check_vip_status
sleep 5 # 每隔 5 秒检测一次
done
MySQL全量备份和增量备份脚本
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#!/bin/bash

# 设置备份目录
BACKUP_DIR="/path/to/backup/directory"

# 设置MySQL数据库连接参数
DB_HOST="localhost"
DB_PORT="3306"
DB_USER="your_username" #MySQL用户名
DB_PASS="your_password" #MySQL密码

# 设置备份保留天数
RETENTION_DAYS=7

# 获取当前日期和时间戳
CURRENT_DATE=$(date +%Y-%m-%d)
CURRENT_TIMESTAMP=$(date +%Y%m%d%H%M%S)

# 执行全量备份命令
perform_full_backup() {
# 检查全量备份目录是否为空,如果为空,则执行全量备份
if [ -z "$(ls -A $BACKUP_DIR)" ]; then
echo "Performing initial full backup..."
innobackupex --user=$DB_USER --password=$DB_PASS --host=$DB_HOST --port=$DB_PORT --no-timestamp $BACKUP_DIR
else
echo "Skipping full backup as the backup directory is not empty."
fi
}

# 执行增量备份命令
perform_incremental_backup() {
# 使用当前时间戳作为增量备份文件名
INCREMENTAL_BACKUP_DIR="$BACKUP_DIR/incremental/$CURRENT_TIMESTAMP"

# 检查全量备份目录是否存在,如果不存在,则执行全量备份
if [ -z "$(ls -A $BACKUP_DIR)" ]; then
echo "Performing initial full backup..."
innobackupex --user=$DB_USER --password=$DB_PASS --host=$DB_HOST --port=$DB_PORT --no-timestamp $BACKUP_DIR
fi

echo "Performing incremental backup..."
innobackupex --user=$DB_USER --password=$DB_PASS --host=$DB_HOST --port=$DB_PORT --no-timestamp --incremental $INCREMENTAL_BACKUP_DIR --incremental-basedir=$BACKUP_DIR

# 删除超出保留天数的备份文件
find $BACKUP_DIR -type d -mtime +$RETENTION_DAYS -exec rm -rf {} \;
}

# 执行全量备份和增量备份
perform_full_backup
perform_incremental_backup

echo "Backup completed successfully."