用 Shell 脚本实现 Redis 一键安装与卸载全流程管理

Redis 是国内外广泛使用的高性能键值数据库,在软件开发、缓存和消息队列等场景避免不了 Redis 的身影。为了方便快速部署,有时我们需要编写自动化脚本,来实现 Redis 的一键安装和一键卸载。本文基于 Redis 3.2.12 版本,结合 CentOS 及类似系统,分享我实现的Redis安装与卸载自动化shell脚本,以及遇到的一些细节和解决方案。


一、脚本功能与结构

1.1 安装脚本主要功能

  • 自动安装 Redis 必要依赖(gcc make jemalloc-devel tcl wget firewalld)
  • 下载指定版本的 Redis 源码包(支持本地压缩包路径)
  • 编译安装 Redis 到指定目录
  • 创建redis系统用户,并配置相应目录权限
  • 交互式设置访问密码、端口、绑定地址、持久化、日志路径等多项配置
  • 生成 systemd 服务脚本,实现 Redis 服务化管理
  • 配置 firewall(firewalld)防火墙端口开放与关闭
  • 启动 Redis 并辅助打印运行状态

1.2 卸载脚本主要功能

  • 停止 Redis 服务,禁止开机自启
  • 删除 systemd 服务文件并刷新 systemd 配置
  • 删除 Redis 安装目录(包括可执行文件、配置文件、日志和数据)
  • 删除 Redis 用户(基于安全和风险考虑,操作前请确认)
  • 关闭防火墙中Redis端口开放

二、运行卸载脚本日志示例

[root@localhost script]# ./uninstall-redis.sh 
=== Redis 卸载流程 ===
[INFO] 停止 Redis 服务...
[INFO] 禁用 Redis 服务开机自启...
Removed symlink /etc/systemd/system/multi-user.target.wants/redis.service.
[INFO] 删除 systemd 服务文件...
[INFO] 删除 Redis 安装目录:/home/environment/redis
[INFO] 删除 redis 用户...
userdel: redis 邮件池 (/var/spool/mail/redis) 未找到
userdel:未找到 redis 的主目录“/home/redis”
[INFO] 关闭 firewalld 上 Redis 端口 6379
success
success
[INFO] Redis 卸载完成!

小提示:
userdel 提示「邮件池未找到」「主目录未找到」并不影响用户删除操作,且是正常信息,因为安装时并未创建 /home/redis 目录也没有邮箱文件。


三、使用这些脚本

  1. 准备环境
    确保你的系统为 CentOS/RHEL,且有网络连接和 root 权限。

  2. 安装 Redis

    chmod +x install-redis.sh
    ./install-redis.sh
    

    根据提示输入相应配置。

  3. 卸载 Redis

    chmod +x uninstall-redis.sh
    ./uninstall-redis.sh
    

    脚本会自动清理服务、文件和用户。


四、总结

  • 通过自定义 shell 脚本自动部署 Redis 节省时间,降低人为配置错误风险
  • 支持交互式定制和默认参数,灵活方便
  • 配合使用卸载脚本,有效避免“残留”,实现完整的安装-卸载闭环
  • 部署前请备份重要数据,尤其是配置文件和持久化文件
  • 根据实际需求针对防火墙、用户权限等可做进一步增强

希望这套Redis一键安装和卸载脚本能帮你快速搭建高可用的缓存环境,也欢迎关注、留言交流!


附录:脚本获取

  • 安装脚本
#!/bin/bash

REDIS_VERSION="3.2.12"
# 安装目录
INSTALL_DIR="/home/environment/redis"
# 安装包路径,优先使用,可不写
LOCAL_TARBALL=""
DOWNLOAD_BASE_URL="http://download.redis.io/releases"
# 可更改端口号
REDIS_PORT=6379
# 预设 Redis 密码,留空则安装时交互询问
REDIS_PASSWORD=""



install_dependencies() {
    echo "[INFO] 安装依赖包..."
    yum install -y gcc make jemalloc-devel tcl wget firewalld || {
        echo "[ERROR] 安装依赖包失败,请检查网络及yum源配置"
        exit 1
    }
}

fetch_redis_source() {
    if [[ -n "$LOCAL_TARBALL" && -f "$LOCAL_TARBALL" ]]; then
        echo "[INFO] 使用用户指定本地压缩包:$LOCAL_TARBALL"
        SRC_TAR="$LOCAL_TARBALL"
    else
        SRC_TAR="redis-$REDIS_VERSION.tar.gz"
        DOWNLOAD_URL="$DOWNLOAD_BASE_URL/$SRC_TAR"
        echo "[INFO] 本地压缩包未指定或不存在,尝试从互联网下载:$DOWNLOAD_URL"
        if ! wget -c "$DOWNLOAD_URL" -O "$SRC_TAR"; then
            echo "[ERROR] 下载 Redis 源码包失败,请检查网络及版本号"
            exit 1
        fi
        SRC_TAR="$SRC_TAR"
    fi
}

compile_install_redis() {
    echo "[INFO] 解压源码包..."
    tar xzf "$SRC_TAR" || {
        echo "[ERROR] 解压失败"
        exit 1
    }
    cd "redis-$REDIS_VERSION" || {
        echo "[ERROR] 目录 redis-$REDIS_VERSION 不存在"
        exit 1
    }

    echo "[INFO] 编译 Redis..."
    make -j$(nproc) || {
        echo "[ERROR] make 编译失败"
        exit 1
    }
    make install PREFIX="$INSTALL_DIR" || {
        echo "[ERROR] make install 失败"
        exit 1
    }
    cd ..
}

setup_user_and_dirs() {
    id redis &>/dev/null || useradd -r -s /sbin/nologin redis
    mkdir -p "$INSTALL_DIR/etc" "$INSTALL_DIR/var" "$INSTALL_DIR/log"
    chown -R redis:redis "$INSTALL_DIR"
}

prompt_user_input() {
    # 如果 REDIS_PASSWORD 为空,则交互询问是否设置密码以及输入密码
    if [[ -z "$REDIS_PASSWORD" ]]; then
        read -p "是否设置 Redis 访问密码?(y/N): " set_pass
        set_pass=${set_pass,,}
        if [[ "$set_pass" == "y" ]]; then
            while true; do
                read -s -p "请输入 Redis 密码: " redis_pass1
                echo
                read -s -p "请再次输入密码确认: " redis_pass2
                echo
                if [[ "$redis_pass1" == "$redis_pass2" && -n "$redis_pass1" ]]; then
                    REDIS_PASSWORD="$redis_pass1"
                    break
                else
                    echo "[WARN] 两次输入不一致或为空,请重试"
                fi
            done
        fi
    else
        # 如果预设变量有值,提示并选择是否继续使用
        while true; do
            read -p "检测到脚本头部预设 Redis 密码,是否使用该密码?(Y/n): " use_pre_pass
            use_pre_pass=${use_pre_pass,,}
            if [[ "$use_pre_pass" == "y" || -z "$use_pre_pass" ]]; then
                echo "将使用预设 Redis 密码。"
                break
            elif [[ "$use_pre_pass" == "n" ]]; then
                REDIS_PASSWORD=""
                # 递归调用进入交互模式输入密码
                prompt_user_input
                return
            else
                echo "请输入 y 或 n。"
            fi
        done
    fi

    read -p "是否允许外部工具连接 Redis (监听所有IP 0.0.0.0)?(y/N): " allow_external
    allow_external=${allow_external,,}
    if [[ "$allow_external" == "y" ]]; then
        BIND_ADDR="0.0.0.0"
    else
        BIND_ADDR="127.0.0.1"
    fi

    read -p "是否允许防火墙开放 Redis 端口 $REDIS_PORT?(y/N): " open_firewall
    open_firewall=${open_firewall,,}

    read -p "是否启用 RDB 持久化(默认启用)?(Y/n): " enable_rdb
    enable_rdb=${enable_rdb,,}
    [[ "$enable_rdb" == "n" ]] && RDB_ENABLED="no" || RDB_ENABLED="yes"

    read -p "是否启用 AOF 持久化(默认禁用)?(y/N): " enable_aof
    enable_aof=${enable_aof,,}
    [[ "$enable_aof" == "y" ]] && AOF_ENABLED="yes" || AOF_ENABLED="no"

    read -p "是否调整最大客户端连接数(默认 10000)?(y/N): " change_max_clients
    change_max_clients=${change_max_clients,,}
    if [[ "$change_max_clients" == "y" ]]; then
        while true; do
            read -p "请输入最大客户端连接数(建议不小于 1000): " max_clients_input
            if [[ "$max_clients_input" =~ ^[0-9]+$ && $max_clients_input -ge 100 ]]; then
                MAX_CLIENTS=$max_clients_input
                break
            else
                echo "请输入有效的数字且不小于100"
            fi
        done
    else
        MAX_CLIENTS=10000
    fi

    read -p "是否自定义日志文件路径(默认$INSTALL_DIR/var/redis.log)?(y/N): " custom_log
    custom_log=${custom_log,,}
    if [[ "$custom_log" == "y" ]]; then
        while true; do
            read -p "请输入日志文件完整路径: " log_path_input
            if [[ -n "$log_path_input" ]]; then
                LOG_FILE="$log_path_input"
                break
            else
                echo "路径不能为空"
            fi
        done
    else
        LOG_FILE="$INSTALL_DIR/var/redis.log"
    fi
}

# 复制默认配置文件,做增量修改
copy_and_modify_conf() {
    SRC_CONF="redis-$REDIS_VERSION/redis.conf"
    CONF_PATH="$INSTALL_DIR/etc/redis.conf"

    echo "[INFO] 复制示例配置文件到安装目录"
    cp "$SRC_CONF" "$CONF_PATH" || {
        echo "[ERROR] 复制配置文件失败"
        exit 1
    }

    echo "[INFO] 修改配置文件"

    # 修改 bind 地址
    sed -i "s/^bind .*/bind $BIND_ADDR/" "$CONF_PATH"

    # 如果选择了设置密码
    if [[ -n "$REDIS_PASSWORD" ]]; then
        # 注释掉原有 requirepass(以防多个)
        sed -i "s/^\(requirepass.*\)/# \1/" "$CONF_PATH"
        # 添加新密码配置到文件末尾
        echo "requirepass $REDIS_PASSWORD" >> "$CONF_PATH"
    else
        # 注释掉所有 requirepass,避免密码限制
        sed -i "s/^\(requirepass.*\)/# \1/" "$CONF_PATH"
    fi

    # 设置日志文件
    sed -i "s@^logfile .*@logfile \"$LOG_FILE\"@" "$CONF_PATH"

    # 设置工作目录
    sed -i "s@^dir .*@dir $INSTALL_DIR/var@" "$CONF_PATH"

    # maxclients
    sed -i "s/^maxclients .*/maxclients $MAX_CLIENTS/" "$CONF_PATH"

    # 配置持久化:RDB
    if [[ "$RDB_ENABLED" == "no" ]]; then
        # 注释掉所有save规则禁用RDB持久化
        sed -i "s/^save/# save/" "$CONF_PATH"
    else
        # 使用默认或保留原有save配置即可,不做处理
        # 如果想自定义 save 规则可在此添加
        # 这里以默认配置为例,就不修改了
        :
    fi

    # 配置持久化:AOF
    if [[ "$AOF_ENABLED" == "yes" ]]; then
        sed -i "s/^appendonly no/appendonly yes/" "$CONF_PATH"
    else
        sed -i "s/^appendonly yes/appendonly no/" "$CONF_PATH"
    fi
}

create_systemd_service() {
    SERVICE_FILE="/etc/systemd/system/redis.service"
    cat > "$SERVICE_FILE" <<EOF
[Unit]
Description=Redis In-Memory Data Store
After=network.target

[Service]
User=redis
Group=redis
ExecStart=$INSTALL_DIR/bin/redis-server $INSTALL_DIR/etc/redis.conf
ExecStop=$INSTALL_DIR/bin/redis-cli -p $REDIS_PORT shutdown
Restart=always
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target
EOF

    systemctl daemon-reload
    systemctl enable redis
}

start_redis() {
    systemctl start redis
    sleep 2
    if systemctl status redis | grep -q running; then
        echo "[INFO] Redis 服务启动成功,运行端口 $REDIS_PORT"
    else
        echo "[ERROR] Redis 服务启动失败,请检查日志"
        journalctl -u redis -n 50 --no-pager
        exit 1
    fi
}

configure_firewall() {
    # 检查 firewalld 是否安装
    if ! command -v firewall-cmd &>/dev/null; then
        echo "[WARN] firewalld 未安装,尝试安装中..."
        yum install -y firewalld || {
            echo "[ERROR] firewalld 安装失败,请手动安装防火墙"
            return
        }
    fi

    # 检查 firewalld 是否正在运行,未运行则尝试启动并设置开机自启
    systemctl is-active --quiet firewalld
    if [[ $? -ne 0 ]]; then
        echo "[WARN] firewalld 未启动,尝试启动并设置开机自启..."
        systemctl start firewalld || {
            echo "[ERROR] firewalld 启动失败,请检查系统日志"
            return
        }
        systemctl enable firewalld
    fi

    # 根据用户选择开放或关闭对应端口
    if [[ "$open_firewall" == "y" ]]; then
        echo "[INFO] 配置 firewalld 开放端口 $REDIS_PORT/tcp"
        firewall-cmd --permanent --add-port=${REDIS_PORT}/tcp
        firewall-cmd --reload
    else
        echo "[INFO] 配置 firewalld 关闭端口 $REDIS_PORT/tcp"
        firewall-cmd --permanent --remove-port=${REDIS_PORT}/tcp &>/dev/null
        firewall-cmd --reload
    fi
}


main() {
    echo "=== Redis 安装脚本 ==="

    read -p "请输入 Redis 源码压缩包本地路径(有则输入完整路径,无则直接回车): " user_tarball
    if [[ -n "$user_tarball" ]]; then
        if [[ -f "$user_tarball" ]]; then
            LOCAL_TARBALL="$user_tarball"
        else
            echo "[ERROR] 指定的压缩包路径不存在,请检查后重试"
            exit 1
        fi
    fi

    install_dependencies
    fetch_redis_source
    compile_install_redis
    setup_user_and_dirs
    prompt_user_input

    copy_and_modify_conf

    create_systemd_service
    configure_firewall
    start_redis

    echo "Redis 安装完成!"
    echo "配置文件: $INSTALL_DIR/etc/redis.conf"
    echo "日志文件: $LOG_FILE"
    echo "默认使用 systemctl 管理服务:"
    echo " - 启动: systemctl start redis"
    echo " - 停止: systemctl stop redis"
    echo " - 重启: systemctl restart redis"
    echo " - 查看状态: systemctl status redis"
}

main "$@"
  • 搭配一键卸载脚本
#!/bin/bash

# Redis 卸载脚本示例

# 以下变量需和安装脚本保持一致
REDIS_PORT=6379
INSTALL_DIR="/home/environment/redis"
SERVICE_FILE="/etc/systemd/system/redis.service"
REDIS_USER="redis"

echo "=== Redis 卸载流程 ==="

# 1. 停止 Redis 服务并禁用开机自启
if systemctl is-active --quiet redis; then
    echo "[INFO] 停止 Redis 服务..."
    systemctl stop redis
fi
if systemctl is-enabled --quiet redis; then
    echo "[INFO] 禁用 Redis 服务开机自启..."
    systemctl disable redis
fi

# 2. 删除 systemd 服务文件并刷新 systemd 配置
if [[ -f "$SERVICE_FILE" ]]; then
    echo "[INFO] 删除 systemd 服务文件..."
    rm -f "$SERVICE_FILE"
    systemctl daemon-reload
fi

# 3. 删除安装目录(包含二进制、配置、数据、日志)
if [[ -d "$INSTALL_DIR" ]]; then
    echo "[INFO] 删除 Redis 安装目录:$INSTALL_DIR"
    rm -rf "$INSTALL_DIR"
fi

# 4. 删除 redis 用户(可选,谨慎操作)
if id "$REDIS_USER" &>/dev/null; then
    echo "[INFO] 删除 redis 用户..."
    userdel -r "$REDIS_USER"
fi

# 5. 关闭防火墙 Redis 端口(仅当 firewalld 存在并运行)
if command -v firewall-cmd &>/dev/null && systemctl is-active --quiet firewalld; then
    echo "[INFO] 关闭 firewalld 上 Redis 端口 $REDIS_PORT"
    firewall-cmd --permanent --remove-port=${REDIS_PORT}/tcp
    firewall-cmd --reload
fi

# 6. 依赖包可选择不卸载,视环境决定
#echo "[INFO] 依赖包卸载 请手动确认"
#yum remove -y gcc make jemalloc-devel tcl wget firewalld

echo "[INFO] Redis 卸载完成!"

版权声明

本文原创,欢迎共享,转载请注明出处。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值