297 lines
8.1 KiB
Bash
297 lines
8.1 KiB
Bash
#!/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
|