Files
2026-07-28 16:03:38 +08:00

297 lines
8.1 KiB
Bash
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
#====================================================
# Swap Builder - Swap 管理工具
# 夏日之瓜×仰望星辰工作室 出品
#====================================================
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
NC='\033[0m'
# 检查 root 权限
check_root() {
if [ "$(id -u)" -ne 0 ]; then
echo -e "${RED}[错误] 此脚本需要 root 权限运行。${NC}"
echo -e "${YELLOW}请使用:curl -sSL swap.fangqihang.cn | sudo bash${NC}"
exit 1
fi
}
# 检查交互环境
check_tty() {
if [ ! -e /dev/tty ]; then
echo -e "${RED}[错误] 无法访问 /dev/tty,请在终端中运行此脚本。${NC}"
exit 1
fi
}
# 打印横幅
print_banner() {
echo -e "${CYAN}"
echo "=================================================="
echo " Swap Builder - Swap 管理工具"
echo "=================================================="
echo " 夏日之瓜×仰望星辰工作室 出品"
echo "=================================================="
echo -e "${NC}"
}
# 显示当前状态
show_status() {
echo -e "${BLUE}---------- 当前系统状态 ----------${NC}"
echo ""
# Swap 设备信息
if command -v swapon &>/dev/null; then
local swap_info=$(swapon --show 2>/dev/null)
if [ -n "$swap_info" ]; then
echo -e "${GREEN}[Swap 设备]${NC}"
echo "$swap_info"
else
echo -e "${YELLOW}[Swap 设备] 当前未启用 Swap${NC}"
fi
fi
echo ""
# 内存信息
if command -v free &>/dev/null; then
echo -e "${GREEN}[内存使用]${NC}"
free -h 2>/dev/null || free -m 2>/dev/null
fi
echo ""
# swappiness
local current_swappiness=$(cat /proc/sys/vm/swappiness 2>/dev/null)
if [ -n "$current_swappiness" ]; then
echo -e "${GREEN}[swappiness] 当前值:${current_swappiness}${NC}"
fi
echo ""
echo -e "${BLUE}-----------------------------------${NC}"
echo ""
}
# 设置 Swap
set_swap() {
echo -e "${CYAN}【设置 Swap】${NC}"
echo ""
echo -e "请输入想要设置的 Swap 大小(单位:MB)"
echo -e "${YELLOW}建议:物理内存的 1~2 倍,例如 2048 = 2GB${NC}"
echo -e "${YELLOW}输入 0 可关闭 Swap${NC}"
echo ""
echo -n "Swap 大小 (MB): "
read swap_size < /dev/tty
echo ""
# 输入校验
if ! [[ "$swap_size" =~ ^[0-9]+$ ]]; then
echo -e "${RED}[错误] 请输入有效的数字!${NC}"
return 1
fi
# 关闭 Swap
if [ "$swap_size" -eq 0 ]; then
echo -e "${YELLOW}正在关闭 Swap...${NC}"
swapoff -a 2>/dev/null
# 从 fstab 中移除 swap 条目(备份后操作)
if grep -q ' swap ' /etc/fstab 2>/dev/null; then
cp /etc/fstab /etc/fstab.bak.$(date +%Y%m%d%H%M%S)
sed -i '/ swap /d' /etc/fstab
echo -e "${GREEN}已备份 /etc/fstab 并移除 Swap 条目${NC}"
fi
echo -e "${GREEN}Swap 已成功关闭!${NC}"
return 0
fi
# 范围检查
if [ "$swap_size" -lt 128 ]; then
echo -e "${RED}[错误] Swap 大小不能小于 128MB${NC}"
return 1
fi
if [ "$swap_size" -gt 65536 ]; then
echo -e "${RED}[错误] Swap 大小不能超过 65536MB (64GB)${NC}"
return 1
fi
# 磁盘空间检查
local available_mb=$(df -m / 2>/dev/null | awk 'NR==2 {print $4}')
local required_mb=$((swap_size + 1024))
if [ -z "$available_mb" ]; then
echo -e "${YELLOW}[警告] 无法检测磁盘空间,继续操作...${NC}"
elif [ "$available_mb" -lt "$required_mb" ]; then
echo -e "${RED}[错误] 磁盘空间不足!${NC}"
echo -e "${YELLOW}可用:${available_mb}MB | 需要:${required_mb}MB(含 1GB 余量)${NC}"
return 1
fi
# 确认操作
echo -e "${YELLOW}即将创建 ${swap_size}MB 的 Swap 文件${NC}"
echo -n "确认继续?(y/n): "
read confirm < /dev/tty
echo ""
if [[ "$confirm" != "y" && "$confirm" != "Y" ]]; then
echo -e "${YELLOW}操作已取消。${NC}"
return 0
fi
# 备份 fstab
cp /etc/fstab /etc/fstab.bak.$(date +%Y%m%d%H%M%S) 2>/dev/null
echo -e "${GREEN}已备份 /etc/fstab${NC}"
# 关闭现有 swap
swapoff -a 2>/dev/null
# 确定 swap 文件路径
local swap_file="/swapfile"
if [ -d "/www" ]; then
swap_file="/www/swap"
fi
# 移除旧文件(如果存在)
if [ -f "$swap_file" ]; then
rm -f "$swap_file"
fi
# 创建 swap 文件
echo -e "${YELLOW}正在创建 Swap 文件(${swap_size}MB...${NC}"
if command -v fallocate &>/dev/null; then
fallocate -l ${swap_size}M "$swap_file" 2>/dev/null
if [ $? -ne 0 ]; then
echo -e "${YELLOW}fallocate 不可用,使用 dd 创建...${NC}"
dd if=/dev/zero of="$swap_file" bs=1M count=$swap_size
fi
else
dd if=/dev/zero of="$swap_file" bs=1M count=$swap_size
fi
# 检查文件是否创建成功
if [ ! -f "$swap_file" ]; then
echo -e "${RED}[错误] Swap 文件创建失败!${NC}"
return 1
fi
# 设置权限
chmod 600 "$swap_file"
# 创建 swap 并启用
mkswap "$swap_file"
swapon "$swap_file"
if [ $? -ne 0 ]; then
echo -e "${RED}[错误] Swap 启用失败!${NC}"
return 1
fi
# 持久化到 fstab(先移除旧条目再添加)
sed -i '/ swap /d' /etc/fstab
echo "$swap_file none swap sw 0 0" >> /etc/fstab
echo ""
echo -e "${GREEN}Swap 设置成功!${NC}"
echo ""
swapon --show 2>/dev/null
echo ""
free -h 2>/dev/null || free -m 2>/dev/null
}
# 设置 swappiness
set_swappiness() {
echo -e "${CYAN}【设置 swappiness】${NC}"
echo ""
echo -e "swappiness 控制系统使用 Swap 的积极程度"
echo -e " ${YELLOW}0${NC} = 尽量不使用 Swap"
echo -e " ${YELLOW}100${NC} = 积极使用 Swap"
echo -e " ${YELLOW}建议${NC}:服务器推荐 10~30"
echo ""
local current=$(cat /proc/sys/vm/swappiness 2>/dev/null)
echo -e "${GREEN}当前 swappiness 值:${current}${NC}"
echo ""
echo -n "请输入 swappiness 值 (0-100): "
read swappiness_val < /dev/tty
echo ""
# 输入校验
if ! [[ "$swappiness_val" =~ ^[0-9]+$ ]]; then
echo -e "${RED}[错误] 请输入有效的数字!${NC}"
return 1
fi
if [ "$swappiness_val" -gt 100 ]; then
echo -e "${RED}[错误] swappiness 值必须在 0~100 之间!${NC}"
return 1
fi
# 临时生效
sysctl -w vm.swappiness=$swappiness_val
# 持久化
if grep -q "^vm.swappiness" /etc/sysctl.conf 2>/dev/null; then
sed -i "s/^vm.swappiness=.*/vm.swappiness=$swappiness_val/" /etc/sysctl.conf
else
echo "vm.swappiness=$swappiness_val" >> /etc/sysctl.conf
fi
echo ""
echo -e "${GREEN}swappiness 已设置为 ${swappiness_val}(已持久化到 /etc/sysctl.conf${NC}"
}
# 主菜单
main_menu() {
while true; do
clear 2>/dev/null
print_banner
show_status
echo -e "${CYAN}请选择操作:${NC}"
echo -e " ${GREEN}1${NC}) 设置 Swap"
echo -e " ${GREEN}2${NC}) 设置优先度(swappiness"
echo -e " ${GREEN}0${NC}) 退出"
echo ""
echo -n "请输入选项 [0-2]: "
read choice < /dev/tty
echo ""
case $choice in
1)
set_swap
;;
2)
set_swappiness
;;
0)
echo -e "${GREEN}感谢使用 Swap Builder${NC}"
echo -e "${CYAN}—— 夏日之瓜×仰望星辰工作室 出品 ——${NC}"
exit 0
;;
*)
echo -e "${RED}无效选项,请重新输入!${NC}"
;;
esac
echo ""
echo -n "按回车键返回主菜单..."
read < /dev/tty
done
}
# 捕获 Ctrl+C
trap 'echo ""; echo -e "${YELLOW}操作已中断。${NC}"; exit 1' INT
# 入口
check_root
check_tty
main_menu