需要修改脚本:NFS_SERVER="192.168.1.1"

指定本机挂载目录:PKG_DIR="/tmp/nfs"

离线依赖包:REQUIRED_PKGS=("gssproxy-0.8.0-19.el8.x86_64.rpm" "nfs-utils-2.3.3-46.el8.x86_64.rpm" "rpcbind-1.2.5-8.el8.x86_64.rpm")

nfs-utils-2.3.3-46.el8.x86_64.rpm

rpcbind-1.2.5-8.el8.x86_64.rpm

gssproxy-0.8.0-19.el8.x86_64.rpm

#!/bin/bash
# 脚本名称:nfs_client_install.sh
# 功能:无外网+纯原生命令
# 依赖命令:ping telnet mount rpm systemctl timeout
# 作者:zach

# 颜色输出
RED='\033[31m'
GREEN='\033[32m'
YELLOW='\033[33m'
NC='\033[0m'

# 全局变量
NFS_SERVER="192.168.1.1"
PKG_DIR="/tmp/nfs"
REQUIRED_PKGS=("gssproxy-0.8.0-19.el8.x86_64.rpm" "nfs-utils-2.3.3-46.el8.x86_64.rpm" "rpcbind-1.2.5-8.el8.x86_64.rpm")

# 错误退出
error_exit() {
    echo -e "${RED}❌ 错误:$1${NC}"
    exit 1
}

# 成功提示
success_msg() {
    echo -e "${GREEN}✅ $1${NC}"
}

# 1. 前置检查(nc→telnet)
pre_check() {
    echo "=== 1/5 前置检查 ==="
    # 检查root
    [ $UID -ne 0 ] && error_exit "请用root用户执行"
    success_msg "Root权限正常"
    
    # 检查明确有的命令(nc→telnet,新增timeout)
    for cmd in ping telnet mount rpm systemctl timeout; do
        ! command -v "$cmd" &> /dev/null && error_exit "缺少命令:$cmd"
    done
    success_msg "基础命令正常"
}

# 2. 纯rpm离线安装(不变)
install_pkgs() {
    echo -e "\n=== 2/5 离线安装NFS包 ==="
    # 检查包是否存在
    [ ! -d "$PKG_DIR" ] && error_exit "离线包目录不存在:$PKG_DIR"
    for pkg in "${REQUIRED_PKGS[@]}"; do
        [ ! -f "$PKG_DIR/$pkg" ] && error_exit "缺少离线包:$pkg"
    done
    success_msg "离线包齐全"
    
    # 纯rpm强制安装(无外网只能--nodeps --force)
    echo "正在安装..."
    rpm -ivh --nodeps --force "$PKG_DIR"/*.rpm &> /dev/null
    # 简单验证
    for pkg_name in gssproxy nfs-utils rpcbind; do
        ! rpm -q "$pkg_name" &> /dev/null && error_exit "安装失败:$pkg_name"
    done
    success_msg "NFS包安装完成"
}

# 3. 启动rpcbind服务(不变)
start_service() {
    echo -e "\n=== 3/5 启动rpcbind ==="
    systemctl start rpcbind
    systemctl enable rpcbind &> /dev/null
    # 验证
    ! systemctl is-active --quiet rpcbind && error_exit "rpcbind启动失败"
    success_msg "rpcbind启动成功(已设开机自启)"
}

# 4. 网络验证(nc→telnet+timeout)
check_network() {
    echo -e "\n=== 4/5 网络验证 ==="
    # Ping测试
    ping -c 2 -W 1 "$NFS_SERVER" &> /dev/null
    [ $? -ne 0 ] && error_exit "无法Ping通服务端:$NFS_SERVER"
    success_msg "Ping $NFS_SERVER 正常"
    # 测试NFS端口2049
    echo "测试NFS端口2049..."
    # 使用 Bash 原生方式检测(最稳妥),超时设为3秒
    timeout 3 bash -c "cat < /dev/tcp/$NFS_SERVER/2049" > /dev/null 2>&1
    RET_CODE=$?
    # 退出码 0=连接成功立即断开;124=连接成功但被超时终止;这两种都算通
    if [ $RET_CODE -eq 0 ] || [ $RET_CODE -eq 124 ]; then
        success_msg "端口2049连通正常"
    else
        error_exit "NFS端口2049不通 (退出码: $RET_CODE)"
    fi    
}

# 5. 配置挂载(不变)
config_mount() {
    echo -e "\n=== 5/5 配置挂载 ==="
    # 输入本地目录
    while true; do
        read -p "请输入本机挂载目录(如/mnt/nfs):" LOCAL_DIR
        [ -z "$LOCAL_DIR" ] && echo "目录不能为空" && continue
        # 创建目录
        mkdir -p "$LOCAL_DIR"
        [ ! -d "$LOCAL_DIR" ] && error_exit "无法创建目录:$LOCAL_DIR"
        break
    done
    success_msg "本地目录就绪:$LOCAL_DIR"
    
    # 输入服务端目录
    read -p "请输入服务端共享目录(如/data/cert):" REMOTE_DIR
    [ -z "$REMOTE_DIR" ] && error_exit "服务端目录不能为空"
    
    # 直接尝试挂载(最真实的验证)
    echo "正在挂载:$NFS_SERVER:$REMOTE_DIR -> $LOCAL_DIR"
    mount -t nfs "$NFS_SERVER:$REMOTE_DIR" "$LOCAL_DIR"
    [ $? -ne 0 ] && error_exit "挂载失败,请检查服务端目录/权限"
    success_msg "挂载成功"
    
    # 配置开机挂载
    FSTAB_LINE="$NFS_SERVER:$REMOTE_DIR $LOCAL_DIR nfs defaults,_netdev 0 0"
    # 备份fstab
    cp /etc/fstab /etc/fstab.nfs.bak
    # 写入(避免重复)
    grep -qF "$FSTAB_LINE" /etc/fstab || echo "$FSTAB_LINE" >> /etc/fstab
    # 验证
    mount -a &> /dev/null
    [ $? -ne 0 ] && error_exit "开机挂载配置异常,已备份fstab"
    success_msg "开机挂载配置完成"
    
    # 最终验证
    echo -e "\n=== 最终验证 ==="
    df -h | grep "$LOCAL_DIR"
    [ $? -eq 0 ] && success_msg "🎉 全部完成!NFS挂载正常"
}

# 主流程
pre_check
install_pkgs
start_service
check_network
config_mount