#!/bin/bash # Redis服务控制脚本 # 支持: start, stop, restart, status # 获取脚本所在目录的绝对路径 SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd) # 切换工作目录到脚本所在目录 cd "$SCRIPT_DIR" # 加载环境变量 load_environment() { # 检查.envrc文件是否存在 if [ ! -f .envrc ]; then echo "⚠️ 警告: 未找到.envrc文件,将使用默认配置" return 0 fi # 创建临时文件用于存储解密结果 local temp_env=$(mktemp) local success=1 # 首先尝试使用direnv加载(如果安装了) if command -v direnv &> /dev/null; then echo "📋 正在通过direnv加载环境变量..." # 捕获direnv输出到临时文件以便检查错误 eval "$(direnv export zsh)" 2>$temp_env # 检查REDIS_PASSWORD是否成功设置,如果未设置且.envrc存在,则执行direnv allow if [ -z "$REDIS_PASSWORD" ] && [ -f ".envrc" ]; then echo "⚠️ 检测到需要执行direnv allow来授权环境变量文件" direnv allow echo "🔄 重新加载环境变量..." eval "$(direnv export zsh)" 2>$temp_env fi # 检查是否有错误输出 if grep -q "error" "$temp_env" || grep -q "Error" "$temp_env"; then echo "❌ 错误: 环境变量加载失败,请检查主密钥是否正确" cat "$temp_env" rm "$temp_env" return 1 fi # 检查REDIS_PASSWORD是否成功设置 if [ -z "$REDIS_PASSWORD" ]; then echo "❌ 错误: Redis密码解密失败,请检查主密钥是否正确" rm "$temp_env" return 1 fi success=0 fi # 如果direnv加载失败或未安装,尝试直接加载.envrc if [ $success -ne 0 ]; then echo "📋 正在直接加载环境变量..." # 逐个处理环境变量,特别是需要特别处理REDIS_PASSWORD解密 local other_vars=$(grep -E '^export REDIS_' .envrc | grep -v 'REDIS_PASSWORD' | sed 's/^export //') # 导出除REDIS_PASSWORD外的其他变量 if [ ! -z "$other_vars" ]; then export $other_vars fi # 单独处理REDIS_PASSWORD的解密,捕获错误 local openssl_cmd=$(grep -E '^export REDIS_PASSWORD=' .envrc | sed 's/^export REDIS_PASSWORD=//') if [ ! -z "$openssl_cmd" ]; then echo "🔑 请输入加密文件主密钥:" # 执行解密命令并捕获错误 local decrypted_pwd=$(eval "$openssl_cmd" 2>$temp_env) local decrypted_success=$? # 检查解密是否成功 if [ $decrypted_success -ne 0 ] || grep -q "error" "$temp_env"; then echo "❌ 错误: 主密钥错误,解密失败!" cat "$temp_env" rm "$temp_env" return 1 fi # 设置解密后的密码 export REDIS_PASSWORD="$decrypted_pwd" echo "✅ 密码解密成功" fi fi # 清理临时文件 rm -f "$temp_env" return 0 } # 检查Docker是否安装 check_docker() { if ! command -v docker &> /dev/null; then echo "❌ 错误: 未找到docker命令,请先安装Docker" return 1 fi if ! command -v docker-compose &> /dev/null; then echo "❌ 错误: 未找到docker-compose命令,请先安装" return 1 fi if ! docker info &> /dev/null; then echo "❌ 错误: Docker守护进程未运行或无权限访问" return 1 fi return 0 } # 获取容器名称 get_container_name() { # 优先使用环境变量中的容器名,否则使用默认值 local default_name="redis" echo "${REDIS_CONTAINER_NAME:-$default_name}" } # 启动服务 start_service() { echo "🚀 正在启动Redis服务..." # 加载环境变量 if ! load_environment; then echo "❌ 加载环境变量失败" return 1 fi # 检查Docker if ! check_docker; then return 1 fi # 启动容器 if docker-compose up -d; then echo "✅ Redis服务启动成功!" echo "📝 容器名称: $(get_container_name)" echo "📝 端口: ${REDIS_PORT:-6379}" return 0 else echo "❌ Redis服务启动失败" return 1 fi } # 停止服务 stop_service() { echo "⏹️ 正在停止Redis服务..." # 加载环境变量 load_environment # 停止容器 if docker-compose down; then echo "✅ Redis服务已停止" return 0 else echo "❌ Redis服务停止失败" return 1 fi } # 重启服务 restart_service() { echo "🔄 正在重启Redis服务..." if ! stop_service; then echo "❌ 停止服务失败,重启中断" return 1 fi echo "" if ! start_service; then echo "❌ 启动服务失败,重启不完全" return 1 fi echo "✅ Redis服务重启成功!" return 0 } # 查看服务状态 status_service() { echo "📊 Redis服务状态检查..." # 加载环境变量 load_environment local container_name=$(get_container_name) # 检查容器是否存在 if docker ps -a | grep -q "$container_name"; then # 检查容器是否正在运行 if docker ps | grep -q "$container_name"; then echo "✅ Redis服务正在运行" echo "" echo "详细信息:" docker ps | grep "$container_name" # 尝试健康检查 if docker-compose ps | grep -q "$container_name.*Up.*healthy"; then echo "" echo "✅ 健康检查状态: 正常" else echo "" echo "⚠️ 健康检查状态: 待检查" # 运行健康检查命令 echo "运行健康检查..." if docker-compose exec -T redis redis-cli -a "${REDIS_PASSWORD:-123456}" ping; then echo "✅ 连接测试成功" else echo "⚠️ 连接测试失败,请检查配置" fi fi return 0 else echo "❌ Redis服务已停止" echo "" echo "停止的容器信息:" docker ps -a | grep "$container_name" return 1 fi else echo "❌ Redis容器不存在" echo "请使用 './service start' 启动服务" return 1 fi } # 显示帮助信息 show_help() { echo "📚 Redis服务控制脚本使用说明" echo "======================================" echo "命令:" echo " start - 启动Redis服务" echo " stop - 停止Redis服务" echo " restart - 重启Redis服务" echo " status - 查看Redis服务状态" echo " help - 显示此帮助信息" echo "======================================" echo "示例:" echo " ./service start # 启动服务" echo " ./service status # 查看状态" echo "======================================" } # 主函数 main() { case "$1" in start) start_service ;; stop) stop_service ;; restart) restart_service ;; status) status_service ;; help|--help|h|--h) show_help ;; *) echo "❌ 未知命令: $1" show_help return 1 ;; esac } # 执行主函数 main "$@" # 退出并返回状态码 exit $?