Files
script/swap.sh
2025-09-14 17:34:24 +08:00

232 lines
5.5 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.

#!/usr/bin/env bash
# Linux 交换文件管理脚本
# 描述: 在 Linux VPS 上添加或删除交换文件
set -euo pipefail # 遇到错误、未定义变量、管道失败时退出
# 颜色定义
readonly RED='\033[0;31m'
readonly GREEN='\033[0;32m'
readonly YELLOW='\033[1;33m'
readonly NC='\033[0m' # 无颜色
# 配置项
readonly SWAPFILE="/swapfile"
readonly SCRIPT_NAME="$(basename "$0")"
# 日志输出函数
log_info() {
echo -e "${GREEN}[信息]${NC} $*"
}
log_warn() {
echo -e "${YELLOW}[警告]${NC} $*"
}
log_error() {
echo -e "${RED}[错误]${NC} $*" >&2
}
# 检查是否以 root 权限运行
check_root() {
if [[ $EUID -ne 0 ]]; then
log_error "此脚本必须以 root 权限运行!"
log_info "请使用: sudo $SCRIPT_NAME"
exit 1
fi
}
# 检查系统是否支持交换文件(非 OpenVZ
check_virtualization() {
if [[ -d "/proc/vz" ]] && [[ ! -d "/proc/bc" ]]; then
log_error "OpenVZ 容器不支持交换文件!"
exit 1
fi
}
# 验证交换文件大小输入
validate_swap_size() {
local size="$1"
if ! [[ "$size" =~ ^[0-9]+$ ]] || [[ "$size" -lt 64 ]]; then
log_error "无效的交换文件大小。必须是数字且 >= 64 MB"
return 1
fi
# 检查可用磁盘空间
local available_space
available_space=$(df / | awk 'NR==2 {print int($4/1024)}')
if [[ "$size" -gt "$available_space" ]]; then
log_error "磁盘空间不足。可用: ${available_space}MB需要: ${size}MB"
return 1
fi
return 0
}
# 获取系统内存大小
get_memory_size() {
awk '/MemTotal/ {print int($2/1024)}' /proc/meminfo
}
# 检查交换文件是否已存在
swap_exists() {
grep -q "$SWAPFILE" /etc/fstab 2>/dev/null
}
# 显示当前交换文件信息
show_swap_info() {
log_info "当前交换文件信息:"
if [[ -f /proc/swaps ]]; then
cat /proc/swaps
fi
echo
grep "Swap" /proc/meminfo || true
}
# 添加交换文件
add_swap() {
if swap_exists; then
log_error "交换文件已存在!"
log_info "请先使用选项 2 删除现有的交换文件"
return 1
fi
local memory_mb
memory_mb=$(get_memory_size)
local suggested_size=$((memory_mb * 2))
echo
log_info "当前系统内存: ${memory_mb}MB"
log_info "建议交换文件大小: ${suggested_size}MB (内存的2倍)"
echo
read -rp "请输入交换文件大小MB直接回车使用建议值 ${suggested_size}MB: " swap_size
swap_size=${swap_size:-$suggested_size}
if ! validate_swap_size "$swap_size"; then
return 1
fi
log_info "正在创建 ${swap_size}MB 交换文件..."
# 使用更高效的方式创建交换文件
if command -v fallocate >/dev/null 2>&1; then
fallocate -l "${swap_size}M" "$SWAPFILE"
else
dd if=/dev/zero of="$SWAPFILE" bs=1M count="$swap_size" status=progress
fi
# 设置正确的权限
chmod 600 "$SWAPFILE"
# 设置交换文件
mkswap "$SWAPFILE"
swapon "$SWAPFILE"
# 添加到 fstab 以实现持久化
echo "$SWAPFILE none swap sw 0 0" >> /etc/fstab
log_info "交换文件创建成功!"
echo
show_swap_info
}
# 删除交换文件
remove_swap() {
if ! swap_exists; then
log_warn "未找到需要删除的交换文件"
return 0
fi
log_info "正在删除交换文件..."
# 关闭交换
if swapon --show | grep -q "$SWAPFILE"; then
swapoff "$SWAPFILE"
fi
# 从 fstab 中移除
if grep -q "$SWAPFILE" /etc/fstab; then
sed -i "\|$SWAPFILE|d" /etc/fstab
fi
# 删除交换文件
if [[ -f "$SWAPFILE" ]]; then
rm -f "$SWAPFILE"
fi
# 清理缓存
sync
echo 3 > /proc/sys/vm/drop_caches 2>/dev/null || true
log_info "交换文件删除成功!"
echo
show_swap_info
}
# 显示菜单
show_menu() {
clear
cat << 'EOF'
╔══════════════════════════════════════╗
║ Linux 交换文件管理 ║
╠══════════════════════════════════════╣
║ 1. 添加交换文件 ║
║ 2. 删除交换文件 ║
║ 3. 显示交换文件信息 ║
║ 4. 退出程序 ║
╚══════════════════════════════════════╝
EOF
echo
}
# 主菜单循环
main_menu() {
while true; do
show_menu
read -rp "请选择操作 [1-4]: " choice
echo
case "$choice" in
1)
add_swap
;;
2)
remove_swap
;;
3)
show_swap_info
;;
4)
log_info "再见!"
exit 0
;;
*)
log_error "无效选择。请输入 1-4"
sleep 2
continue
;;
esac
echo
read -rp "按回车键继续..."
done
}
# 主函数
main() {
# 执行系统检查
check_root
check_virtualization
# 启动主菜单
main_menu
}
# 脚本入口点
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
main "$@"
fi