From 526d9983a2abdc065dac51688bf3a9882064054b Mon Sep 17 00:00:00 2001 From: joy Date: Sat, 8 Nov 2025 14:09:53 +0800 Subject: [PATCH] ad asdff --- nfs.sh | 533 --------------------------------------------------------- 1 file changed, 533 deletions(-) delete mode 100644 nfs.sh diff --git a/nfs.sh b/nfs.sh deleted file mode 100644 index b86f588..0000000 --- a/nfs.sh +++ /dev/null @@ -1,533 +0,0 @@ -#!/bin/bash -set -euo pipefail # 严格模式:报错即退出、禁止未定义变量、管道错误传递 - -############################################################################## -# 常量定义(默认值,可通过参数覆盖) -############################################################################## -DEFAULT_SHARE_DIRS="/opt/data" # 默认共享目录 -EXPORTS_FILE="/etc/exports" # NFS配置文件路径 -BACKUP_SUFFIX=$(date +%Y%m%d%H%M%S) # 备份文件后缀(时间戳,避免覆盖) -# NFS共享权限模板({DIR}会自动替换为实际共享目录) -# 权限说明:rw(读写)、sync(同步写入)、no_root_squash(保留root权限)、no_all_squash(保留用户权限)、insecure(允许非特权端口访问) -NFS_CONFIG_TEMPLATE="{DIR} *(rw,sync,no_root_squash,no_all_squash,insecure)" -TEST_MOUNT_DIR_PREFIX="/mnt/nfs_test_$$" # 临时测试挂载点前缀($$为进程ID,确保唯一性) - -############################################################################## -# 全局变量(通过命令行参数初始化) -############################################################################## -ACTION="" # 操作类型:install(安装) / uninstall(卸载) -SHARE_DIRS=() # 共享目录数组(支持多个目录) -OS_TYPE="" # 系统类型(提前检测,避免重复调用) - -############################################################################## -# 工具函数(中文注释) -############################################################################## -# 日志输出(带时间戳,便于排查问题) -log() { - echo "[$(date +'%Y-%m-%d %H:%M:%S')] $1" -} - -# 错误退出(打印错误信息后终止脚本) -error_exit() { - log "ERROR: $1" - exit 1 -} - -# 检查是否为root用户(NFS安装/卸载需要root权限) -check_root() { - if [ $EUID -ne 0 ]; then - error_exit "请使用root用户运行脚本(执行 sudo -i 或 su - 切换)" - fi -} - -# 检测系统发行版(返回:centos/ubuntu/debian,适配不同系统的包管理) -detect_os() { - if [ -f /etc/os-release ]; then - . /etc/os-release - case $ID in - centos|rhel) echo "centos" ;; - ubuntu) echo "ubuntu" ;; - debian) echo "debian" ;; - *) error_exit "不支持的系统发行版:$ID(仅支持CentOS/RHEL 7+、Ubuntu 18.04+、Debian 9+)" ;; - esac - else - error_exit "无法检测系统发行版(缺少/etc/os-release文件)" - fi -} - -# 目录路径转义(将 / 替换为 \/,避免sed命令语法冲突) -escape_dir() { - local dir="$1" - echo "${dir//\//\\/}" # 替换所有 / 为 \/ -} - -# 检查服务是否正在运行 -is_service_running() { - local service_name=$1 - systemctl is-active --quiet "$service_name" 2>/dev/null -} - -# 修复Ubuntu/Debian下NFS服务启动异常(核心修复函数) -fix_ubuntu_nfs_start() { - log "开始修复NFS服务启动环境(Ubuntu/Debian)" - - # 1. 停止残留服务进程,避免状态冲突 - log "清理残留NFS相关进程" - pkill -f nfsd || true - pkill -f rpc.mountd || true - - # 2. 确保依赖服务(rpcbind)启动(Ubuntu 18.04+ 部分版本rpcbind默认未启动) - log "启动依赖服务:rpcbind" - systemctl enable --now rpcbind || error_exit "rpcbind服务启动失败(NFS核心依赖)" - - # 3. 校验/etc/exports配置语法(避免配置错误导致服务启动失败) - log "校验NFS配置文件语法($EXPORTS_FILE)" - if ! exportfs -r; then # 重载配置并检查语法 - error_exit "NFS配置文件语法错误!请检查 $EXPORTS_FILE 内容(比如目录路径、权限参数是否正确)" - fi - log "NFS配置语法校验通过" - - # 4. 重启nfs-kernel-server服务(分两步:停止→启动,避免状态残留) - log "重启nfs-kernel-server服务" - systemctl stop nfs-kernel-server || true # 确保服务已停止 - sleep 2 # 等待进程清理 - if systemctl start nfs-kernel-server; then - log "nfs-kernel-server服务启动成功" - systemctl enable nfs-kernel-server || log "警告:设置nfs-kernel-server开机自启失败(不影响当前使用)" - else - # 启动失败时输出详细日志,便于排查 - log "nfs-kernel-server服务启动失败,查看详细错误日志:" - journalctl -xeu nfs-kernel-server | tail -20 - error_exit "nfs-kernel-server服务启动失败(见上方错误日志)" - fi -} - -# 解析命令行参数(处理--install/--uninstall/--share-dirs参数) -parse_args() { - if [ $# -eq 0 ]; then - show_help # 无参数时显示帮助信息 - exit 0 - fi - - # 遍历所有传入参数 - for arg in "$@"; do - case $arg in - --install) - ACTION="install" - ;; - --uninstall) - ACTION="uninstall" - ;; - --share-dirs=*) - # 提取--share-dirs后的目录字符串(逗号分隔) - local dir_str=${arg#--share-dirs=} - # 按逗号分割为数组 - IFS=',' read -r -a dir_array <<< "$dir_str" - # 处理目录数组:去重、过滤空值、校验绝对路径 - for dir in "${dir_array[@]}"; do - dir=$(echo "$dir" | xargs) # 去除目录名前后的空格 - if [ -z "$dir" ]; then - log "警告:跳过空的共享目录(可能是逗号前后多写了空格)" - continue - fi - # 校验是否为绝对路径(必须以/开头) - if [[ ! "$dir" =~ ^/ ]]; then - error_exit "共享目录必须是绝对路径(当前输入:$dir),例如 /opt/data" - fi - # 去重:如果目录已在数组中,不再重复添加 - if ! [[ " ${SHARE_DIRS[@]} " =~ " $dir " ]]; then - SHARE_DIRS+=("$dir") - fi - done - ;; - -h|--help) - show_help - exit 0 - ;; - *) - error_exit "无效参数:$arg,请使用 --help 查看正确用法" - ;; - esac - done - - # 校验必填参数:必须指定--install或--uninstall - if [ -z "$ACTION" ]; then - error_exit "必须指定操作类型:--install(安装) 或 --uninstall(卸载)" - fi - - # 若未指定--share-dirs,使用默认共享目录 - if [ ${#SHARE_DIRS[@]} -eq 0 ]; then - SHARE_DIRS=($DEFAULT_SHARE_DIRS) - log "未指定共享目录,使用默认值:${SHARE_DIRS[*]}" - else - log "已指定共享目录列表:${SHARE_DIRS[*]}" - fi -} - -# 显示帮助信息(中文说明,方便用户使用) -show_help() { - echo "======================================= NFS一键安装卸载脚本 =======================================" - echo "用法:$0 [选项]" - echo "核心选项:" - echo " --install 安装NFS服务端+客户端,并配置共享目录(全程使用root权限)" - echo " --uninstall 卸载NFS服务端+客户端,清理相关配置(保留数据)" - echo " --share-dirs=DIR1,DIR2 指定共享目录(多个目录用逗号分隔,必须为绝对路径)" - echo " --help/-h 显示当前帮助信息" - echo "" - echo "使用示例:" - echo " 1. 安装NFS(使用默认共享目录 /opt/data):" - echo " $0 --install" - echo " 2. 安装NFS(指定多个共享目录):" - echo " $0 --install --share-dirs=/opt/data1,/opt/data2,/mnt/nfs_share" - echo " 3. 卸载NFS(清理默认共享目录的配置):" - echo " $0 --uninstall" - echo " 4. 卸载NFS(清理指定共享目录的配置):" - echo " $0 --uninstall --share-dirs=/opt/data1,/mnt/nfs_share" - echo "==================================================================================================" -} - -# 打印NFS常用维护命令(用户要求新增) -print_maintain_commands() { - log "======================================= NFS常用维护命令 =======================================" - log "📊 查看NFS服务状态:" - if [ "$OS_TYPE" = "centos" ]; then - log " systemctl status nfs-server" - else - log " systemctl status nfs-kernel-server" - fi - log "" - log "🔄 重启NFS服务:" - if [ "$OS_TYPE" = "centos" ]; then - log " systemctl restart nfs-server" - else - log " systemctl restart nfs-kernel-server" - fi - log "" - log "📁 查看已配置的NFS共享目录:" - log " exportfs -v" - log "" - log "⚙️ 重载NFS配置(修改/etc/exports后执行):" - log " exportfs -r" - log "" - log "🖥️ 客户端挂载NFS共享(示例):" - log " mount -t nfs 服务器IP:/共享目录 本地目标目录(如:mount -t nfs 192.168.1.100:/opt/data /mnt/client_data)" - log "" - log "🗑️ 客户端卸载NFS共享:" - log " umount 本地目标目录(如:umount /mnt/client_data)" - log "" - log "🔥 查看NFS服务日志(排查问题):" - if [ "$OS_TYPE" = "centos" ]; then - log " journalctl -u nfs-server -f" - else - log " journalctl -u nfs-kernel-server -f" - fi - log "==================================================================================================" -} - -############################################################################## -# 安装NFS服务(支持多共享目录,中文步骤说明) -############################################################################## -install_nfs() { - log "开始安装NFS服务端+客户端(系统:$OS_TYPE,共享目录:${SHARE_DIRS[*]},全程使用root权限)" - - ########################################################################## - # 步骤1:安装NFS依赖包(根据系统类型选择yum或apt) - ########################################################################## - log "步骤1/6:安装NFS相关依赖包" - case $OS_TYPE in - centos) - # CentOS/RHEL:nfs-utils(服务端+客户端)、rpcbind(端口映射) - yum install -y nfs-utils rpcbind || error_exit "YUM安装依赖失败,请检查yum源是否正常" - ;; - ubuntu|debian) - # Ubuntu/Debian:nfs-kernel-server(服务端)、nfs-common(客户端)、rpcbind(依赖) - apt update -y >/dev/null 2>&1 || error_exit "APT更新源失败,请检查网络或apt源配置" - apt install -y nfs-kernel-server nfs-common rpcbind || error_exit "APT安装依赖失败" - ;; - esac - log "依赖包安装完成" - - ########################################################################## - # 步骤2:创建共享目录并设置全权限(777+root属主,满足用户要求) - ########################################################################## - log "步骤2/6:创建共享目录并配置全权限(共${#SHARE_DIRS[@]}个目录,root属主)" - for dir in "${SHARE_DIRS[@]}"; do - if [ -d "$dir" ]; then - log "共享目录 $dir 已存在,跳过创建" - else - # -p:递归创建父目录(如/opt/data不存在时,自动创建/opt和/opt/data) - mkdir -p "$dir" || error_exit "创建共享目录 $dir 失败(权限不足或路径非法)" - log "成功创建共享目录:$dir" - fi - # 设置全权限(777),保留root属主(创建目录时默认就是root,无需额外chown) - chmod 777 "$dir" || error_exit "设置 $dir 权限为777失败" - log "目录 $dir:权限配置完成(全权限777,属主root:root)" - done - - ########################################################################## - # 步骤3:配置/etc/exports(NFS核心配置文件,先备份再修改) - ########################################################################## - log "步骤3/6:配置NFS共享(自动备份原有配置)" - # 备份原有配置文件(添加时间戳后缀,便于回滚) - if [ -f "$EXPORTS_FILE" ]; then - cp "$EXPORTS_FILE" "${EXPORTS_FILE}.bak.${BACKUP_SUFFIX}" || error_exit "备份 $EXPORTS_FILE 失败" - log "已备份原有配置文件:${EXPORTS_FILE}.bak.${BACKUP_SUFFIX}" - fi - - # 批量添加/更新共享目录配置(核心修复:使用转义后的目录路径) - for dir in "${SHARE_DIRS[@]}"; do - local escaped_dir=$(escape_dir "$dir") # 转义目录中的 / - # 替换配置模板中的{DIR}为实际目录 - local nfs_config=${NFS_CONFIG_TEMPLATE//\{DIR\}/$dir} - # 若该目录已存在配置,先删除旧配置(避免重复) - if grep -q "^${escaped_dir}" "$EXPORTS_FILE" 2>/dev/null; then - log "目录 $dir 的NFS配置已存在,更新为最新配置" - # sed命令使用转义后的目录,避免语法冲突 - sed -i "/^${escaped_dir}/d" "$EXPORTS_FILE" || error_exit "删除 $dir 的旧配置失败" - fi - # 写入新配置到/etc/exports - echo "$nfs_config" >> "$EXPORTS_FILE" || error_exit "写入 $dir 的NFS配置失败" - log "目录 $dir:配置已添加到 $EXPORTS_FILE" - done - - ########################################################################## - # 步骤4:启动NFS服务并设置开机自启(优化启动逻辑,解决启动失败问题) - ########################################################################## - log "步骤4/6:启动NFS服务并配置开机自启" - case $OS_TYPE in - centos) - # CentOS:先启动rpcbind,再启动nfs-server - systemctl enable --now rpcbind || error_exit "启动rpcbind服务失败" - systemctl stop nfs-server || true - sleep 2 - if systemctl start nfs-server; then - systemctl enable nfs-server || log "警告:设置nfs-server开机自启失败" - log "nfs-server服务启动成功" - else - log "nfs-server启动失败,详细日志:" - journalctl -xeu nfs-server | tail -20 - error_exit "nfs-server服务启动失败" - fi - ;; - ubuntu|debian) - # Ubuntu/Debian:使用修复函数启动服务(处理依赖、配置校验、残留清理) - fix_ubuntu_nfs_start - ;; - esac - - # 验证服务是否启动成功 - local service_name=$([ "$OS_TYPE" = "centos" ] && echo "nfs-server" || echo "nfs-kernel-server") - if ! is_service_running "$service_name"; then - error_exit "$service_name服务启动失败,请检查系统日志(journalctl -u $service_name)" - fi - log "$service_name服务启动成功(已配置开机自启)" - - ########################################################################## - # 步骤5:开放防火墙端口(企业环境必备,确保客户端能访问NFS服务) - ########################################################################## - log "步骤5/6:开放防火墙NFS相关端口" - case $OS_TYPE in - centos) - # CentOS使用firewalld - if is_service_running "firewalld"; then - firewall-cmd --permanent --add-service=nfs || error_exit "开放NFS端口(2049)失败" - firewall-cmd --permanent --add-service=rpc-bind || error_exit "开放rpc-bind端口(111)失败" - firewall-cmd --permanent --add-service=mountd || error_exit "开放mountd端口失败" - firewall-cmd --reload || error_exit "防火墙重载配置失败" - log "Firewalld已开放NFS相关端口(2049、111等)" - else - log "Firewalld未运行,跳过端口开放(若后续客户端无法连接,请手动开放端口)" - fi - ;; - ubuntu|debian) - # Ubuntu/Debian使用ufw - if is_service_running "ufw"; then - ufw allow nfs || error_exit "开放NFS端口失败" - ufw allow 111/tcp || error_exit "开放rpcbind端口(111)失败" - ufw reload || error_exit "UFW重载配置失败" - log "UFW已开放NFS端口(2049)和rpcbind端口(111)" - else - log "UFW未运行,跳过端口开放(若后续客户端无法连接,请手动开放端口)" - fi - ;; - esac - - ########################################################################## - # 步骤6:测试验证(每个共享目录都执行挂载+读写测试,确保可用) - ########################################################################## - log "步骤6/6:测试所有共享目录的可用性" - for dir in "${SHARE_DIRS[@]}"; do - # 为每个目录创建唯一的临时挂载点(替换/为_,避免路径冲突) - local test_mount_dir="${TEST_MOUNT_DIR_PREFIX}_$(echo "$dir" | tr '/' '_')" - # 创建临时挂载点 - mkdir -p "$test_mount_dir" || error_exit "创建测试挂载点 $test_mount_dir 失败" - # 本地挂载测试(使用localhost模拟客户端) - log "正在测试挂载:localhost:$dir -> $test_mount_dir" - mount -t nfs localhost:"$dir" "$test_mount_dir" || error_exit "目录 $dir 挂载测试失败(NFS配置可能有误)" - # 读写测试:创建测试文件并验证内容 - local test_file="${test_mount_dir}/nfs_test_${BACKUP_SUFFIX}.txt" - echo "NFS测试内容:$(date) - 共享目录:$dir(root权限)" > "$test_file" || error_exit "目录 $dir 写入测试失败" - if [ -f "$test_file" ] && grep -q "NFS测试内容" "$test_file"; then - log "目录 $dir:读写测试成功(测试文件路径:$test_file)" - else - error_exit "目录 $dir:读写测试失败(文件创建或读取异常)" - fi - # 卸载临时挂载点并清理 - umount "$test_mount_dir" || error_exit "卸载测试挂载点 $test_mount_dir 失败" - rm -rf "$test_mount_dir" || log "清理测试挂载点 $test_mount_dir 失败(可手动删除)" - done - - ########################################################################## - # 安装完成提示+常用维护命令 - ########################################################################## - log "========================================" - log "🎉 NFS服务安装完成!" - log "📁 共享目录列表:${SHARE_DIRS[*]}" - log "🔑 共享权限:全权限(读写+同步写入+保留root权限)" - log "👤 目录属主:root:root(全程使用root权限)" - log "⚙️ 配置文件:$EXPORTS_FILE(备份文件:${EXPORTS_FILE}.bak.${BACKUP_SUFFIX})" - log "🖥️ 客户端挂载命令:mount -t nfs 服务器IP:共享目录 本地目标目录" - log "========================================" - - # 打印常用维护命令(用户要求) - print_maintain_commands -} - -############################################################################## -# 卸载NFS服务(支持多共享目录清理,中文步骤说明) -############################################################################## -uninstall_nfs() { - log "开始卸载NFS服务端+客户端(系统:$OS_TYPE,清理目录:${SHARE_DIRS[*]})" - - ########################################################################## - # 步骤1:卸载所有NFS挂载点(避免服务删除时因挂载占用失败) - ########################################################################## - log "步骤1/5:卸载所有关联的NFS挂载点" - for dir in "${SHARE_DIRS[@]}"; do - local escaped_dir=$(escape_dir "$dir") # 转义目录中的 / - # 匹配所有挂载了该共享目录的挂载点(转义/避免正则匹配错误) - local mount_points=$(mount | grep -E "nfs.*${escaped_dir}" | awk '{print $3}') - if [ -n "$mount_points" ]; then - for mp in $mount_points; do - log "正在卸载挂载点(关联目录:$dir):$mp" - # -l:强制卸载(即使占用),-f:强制杀死占用进程 - umount -lf "$mp" || log "卸载 $mp 失败(可能已被卸载)" - done - fi - done - # 清理剩余的NFS挂载点(避免遗漏) - local remaining_mounts=$(mount | grep -E "nfs|nfs4" | awk '{print $3}') - if [ -n "$remaining_mounts" ]; then - log "清理剩余的NFS挂载点:$remaining_mounts" - for mp in $remaining_mounts; do - umount -lf "$mp" || true - done - fi - log "挂载点清理完成" - - ########################################################################## - # 步骤2:停止NFS相关服务并禁用开机自启 - ########################################################################## - log "步骤2/5:停止NFS相关服务" - case $OS_TYPE in - centos) - systemctl stop nfs-server rpcbind || true - systemctl disable nfs-server rpcbind || true - ;; - ubuntu|debian) - systemctl stop nfs-kernel-server rpcbind || true - systemctl disable nfs-kernel-server rpcbind || true - ;; - esac - log "NFS相关服务已停止并禁用开机自启" - - ########################################################################## - # 步骤3:清理/etc/exports配置(核心修复:使用转义后的目录路径) - ########################################################################## - log "步骤3/5:清理指定共享目录的NFS配置" - if [ -f "$EXPORTS_FILE" ]; then - for dir in "${SHARE_DIRS[@]}"; do - local escaped_dir=$(escape_dir "$dir") # 转义目录中的 / - if grep -q "^${escaped_dir}" "$EXPORTS_FILE" 2>/dev/null; then - # sed命令使用转义后的目录,避免语法冲突 - sed -i "/^${escaped_dir}/d" "$EXPORTS_FILE" || error_exit "清理 $dir 的NFS配置失败" - log "已清理 $dir 的NFS配置" - else - log "$dir 的NFS配置不存在,跳过清理" - fi - done - # 若配置文件为空,直接删除(避免残留空文件) - if [ ! -s "$EXPORTS_FILE" ]; then - rm -f "$EXPORTS_FILE" || log "删除空配置文件 $EXPORTS_FILE 失败" - log "已删除空的NFS配置文件" - fi - else - log "NFS配置文件 $EXPORTS_FILE 不存在,跳过清理" - fi - - ########################################################################## - # 步骤4:卸载NFS相关依赖包(彻底清理安装文件) - ########################################################################## - log "步骤4/5:卸载NFS相关依赖包" - case $OS_TYPE in - centos) - yum remove -y nfs-utils rpcbind || error_exit "YUM卸载依赖包失败" - ;; - ubuntu|debian) - apt purge -y nfs-kernel-server nfs-common rpcbind || error_exit "APT卸载依赖包失败" - # 自动清理无用依赖 - apt autoremove -y >/dev/null 2>&1 || true - ;; - esac - log "NFS相关依赖包已卸载完成" - - ########################################################################## - # 步骤5:提示共享目录数据处理(默认保留,避免误删业务数据) - ########################################################################## - log "步骤5/5:共享目录数据处理提示" - for dir in "${SHARE_DIRS[@]}"; do - if [ -d "$dir" ]; then - log "共享目录 $dir 仍存在(已保留其中数据,属主root:root),如需删除请执行:rm -rf '$dir'" - else - log "共享目录 $dir 不存在,跳过提示" - fi - done - - ########################################################################## - # 卸载完成提示+常用维护命令(用户要求) - ########################################################################## - log "========================================" - log "🗑️ NFS服务卸载完成!" - log "✅ 已清理内容:NFS服务、指定共享目录配置、相关依赖包" - log "⚠️ 未清理内容:共享目录数据(需手动删除,避免误删重要文件)" - log "📋 已清理的共享目录列表:${SHARE_DIRS[*]}" - log "========================================" - - # 打印常用维护命令(用户要求) - print_maintain_commands -} - -############################################################################## -# 主逻辑(脚本入口) -############################################################################## -main() { - check_root # 先检查是否为root用户 - parse_args "$@" # 解析命令行参数 - OS_TYPE=$(detect_os) # 检测系统类型并保存(避免重复调用) - - # 根据操作类型执行对应函数 - case $ACTION in - install) - install_nfs - ;; - uninstall) - uninstall_nfs - ;; - *) - error_exit "无效操作类型:$ACTION(仅支持 install 或 uninstall)" - ;; - esac -} - -# 启动主逻辑 -main "$@" \ No newline at end of file