由于需要通过容器部署以上数据库,对Linux又不熟悉,于是使用Grok写了一个数据库管理脚本。如下:
#!/bin/bash
# 容器数据库管理工具
# 支持PostgreSQL、MySQL和Redis容器的管理
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
PURPLE='\033[0;35m'
CYAN='\033[0;36m'
NC='\033[0m' # 无颜色
# 全局设置
CLEAR_SCREEN=true # 是否在菜单间清屏
# 检查Docker是否安装
check_docker() {
if ! command -v docker &> /dev/null; then
echo -e "${RED}错误: Docker未安装或不在PATH中。请先安装Docker。${NC}"
exit 1
fi
}
# 查找数据库容器
find_containers() {
echo -e "${BLUE}正在搜索数据库容器...${NC}"
# 查找PostgreSQL容器
pg_containers=()
pg_images=()
pg_names=()
pg_running_status=()
# 获取所有运行中的PostgreSQL容器
while IFS= read -r container_id; do
if [ -n "$container_id" ]; then
pg_containers+=("$container_id")
pg_images+=("$(docker inspect --format='{{.Config.Image}}' $container_id)")
pg_names+=("$(docker inspect --format='{{.Name}}' $container_id | sed 's/\///')")
pg_running_status+=(true)
fi
done < <(docker ps | grep -E "postgres|pgvector" | awk '{print $1}')
# 获取所有已停止的PostgreSQL容器
while IFS= read -r container_id; do
if [ -n "$container_id" ] && ! [[ " ${pg_containers[@]} " =~ " ${container_id} " ]]; then
pg_containers+=("$container_id")
pg_images+=("$(docker inspect --format='{{.Config.Image}}' $container_id)")
pg_names+=("$(docker inspect --format='{{.Name}}' $container_id | sed 's/\///')")
pg_running_status+=(false)
fi
done < <(docker ps -a | grep -E "postgres|pgvector" | awk '{print $1}')
# 查找MySQL容器
mysql_container=$(docker ps | grep -E "mysql" | awk '{print $1}' | head -1)
if [ -z "$mysql_container" ]; then
mysql_container=$(docker ps -a | grep -E "mysql" | awk '{print $1}' | head -1)
mysql_running=false
else
mysql_running=true
fi
# 查找Redis容器
redis_container=$(docker ps | grep -E "redis" | awk '{print $1}' | head -1)
if [ -z "$redis_container" ]; then
redis_container=$(docker ps -a | grep -E "redis" | awk '{print $1}' | head -1)
redis_running=false
else
redis_running=true
fi
# 获取容器详细信息
if [ -n "$mysql_container" ]; then
mysql_image=$(docker inspect --format='{{.Config.Image}}' $mysql_container)
mysql_name=$(docker inspect --format='{{.Name}}' $mysql_container | sed 's/\///')
fi
if [ -n "$redis_container" ]; then
redis_image=$(docker inspect --format='{{.Config.Image}}' $redis_container)
redis_name=$(docker inspect --format='{{.Name}}' $redis_container | sed 's/\///')
fi
}
# 检查容器状态并提供启动选项
check_container_status() {
local container_id=$1
local container_name=$2
local container_image=$3
local running=$4
if [ -z "$container_id" ]; then
echo -e "${YELLOW}未找到${container_name}容器${NC}"
return 1
fi
if [ "$running" = false ]; then
echo -e "${YELLOW}容器 ${container_name} (${container_id}) 当前已停止${NC}"
read -p "是否启动该容器? (y/n): " start_choice
if [[ $start_choice == [yY] || $start_choice == [yY][eE][sS] ]]; then
echo -e "${BLUE}正在启动容器 ${container_id}...${NC}"
docker start $container_id
if [ $? -eq 0 ]; then
echo -e "${GREEN}容器已成功启动${NC}"
return 0
else
echo -e "${RED}启动容器失败${NC}"
return 1
fi
else
echo -e "${YELLOW}容器未启动,无法执行管理操作${NC}"
return 1
fi
else
echo -e "${GREEN}容器 ${container_name} (${container_image}) 正在运行${NC}"
return 0
fi
}
# 显示主菜单
show_main_menu() {
if [ "$CLEAR_SCREEN" = true ]; then
clear
else
echo ""
echo -e "${BLUE}----------------------------------------${NC}"
echo ""
fi
echo -e "${CYAN}========================================"
echo -e " 容器数据库管理工具 v1.0"
echo -e "========================================${NC}"
echo -e "请选择要管理的数据库:"
# 显示PostgreSQL容器选项
if [ ${#pg_containers[@]} -gt 0 ]; then
echo -e "${GREEN}PostgreSQL 容器:${NC}"
for i in "${!pg_containers[@]}"; do
if [ "${pg_running_status[$i]}" = true ]; then
echo -e "${GREEN}$((i+1))) ${pg_names[$i]} (${pg_images[$i]}) ${GREEN}[运行中]${NC}"
else
echo -e "${GREEN}$((i+1))) ${pg_names[$i]} (${pg_images[$i]}) ${RED}[已停止]${NC}"
fi
done
else
echo -e "${YELLOW}未检测到PostgreSQL容器${NC}"
fi
# 显示MySQL选项
pg_count=${#pg_containers[@]}
mysql_option=$((pg_count+1))
if [ -n "$mysql_container" ]; then
if [ "$mysql_running" = true ]; then
echo -e "${GREEN}${mysql_option}) MySQL (${mysql_image}) ${GREEN}[运行中]${NC}"
else
echo -e "${GREEN}${mysql_option}) MySQL (${mysql_image}) ${RED}[已停止]${NC}"
fi
else
echo -e "${YELLOW}未检测到MySQL容器${NC}"
fi
# 显示Redis选项
redis_option=$((mysql_option+1))
if [ -n "$redis_container" ]; then
if [ "$redis_running" = true ]; then
echo -e "${GREEN}${redis_option}) Redis (${redis_image}) ${GREEN}[运行中]${NC}"
else
echo -e "${GREEN}${redis_option}) Redis (${redis_image}) ${RED}[已停止]${NC}"
fi
else
echo -e "${YELLOW}未检测到Redis容器${NC}"
fi
# 设置选项
settings_option=$((redis_option+1))
echo -e "${GREEN}${settings_option}) 设置${NC}"
# 退出选项
exit_option=$((settings_option+1))
echo -e "${YELLOW}${exit_option}) 退出${NC}"
echo ""
read -p "请输入选择 [1-${exit_option}]: " main_choice
}
# 显示设置菜单
show_settings_menu() {
if [ "$CLEAR_SCREEN" = true ]; then
clear
else
echo ""
echo -e "${BLUE}----------------------------------------${NC}"
echo ""
fi
echo -e "${CYAN}========================================"
echo -e " 设置菜单"
echo -e "========================================${NC}"
echo -e "当前设置:"
if [ "$CLEAR_SCREEN" = true ]; then
echo -e "1) 清屏模式: ${GREEN}开启${NC}"
else
echo -e "1) 清屏模式: ${RED}关闭${NC}"
fi
echo -e "2) 重置Redis密码"
echo -e "3) 重置MySQL密码"
echo -e "4) 重置PostgreSQL密码"
echo -e "${YELLOW}5) 返回主菜单${NC}"
echo ""
read -p "请输入选择 [1-5]: " settings_choice
case $settings_choice in
1)
if [ "$CLEAR_SCREEN" = true ]; then
CLEAR_SCREEN=false
echo -e "${YELLOW}清屏模式已关闭${NC}"
else
CLEAR_SCREEN=true
echo -e "${GREEN}清屏模式已开启${NC}"
fi
sleep 1
show_settings_menu
;;
2)
redis_password=""
redis_needs_auth=false
echo -e "${GREEN}Redis密码已重置,下次使用Redis功能时将重新询问密码${NC}"
sleep 1
show_settings_menu
;;
3)
mysql_root_password=""
echo -e "${GREEN}MySQL密码已重置,下次使用MySQL功能时将重新询问密码${NC}"
sleep 1
show_settings_menu
;;
4)
postgres_password=""
pg_superuser=""
echo -e "${GREEN}PostgreSQL密码和超级用户已重置,下次使用PostgreSQL功能时将重新检测${NC}"
sleep 1
show_settings_menu
;;
5)
return
;;
*)
echo -e "${RED}无效选择,请重试${NC}"
sleep 1
show_settings_menu
;;
esac
}
# 检查PostgreSQL容器是否有psql工具
check_psql_in_container() {
local container_id=$1
# 尝试在容器中运行psql命令
if ! docker exec $container_id which psql &>/dev/null; then
echo -e "${YELLOW}警告: 容器中未找到psql命令。尝试使用PostgreSQL官方客户端容器连接...${NC}"
return 1
fi
return 0
}
# 检测PostgreSQL超级用户
detect_pg_superuser() {
local container_id=$1
# 尝试从环境变量获取用户名
local pg_user=$(docker inspect --format='{{range .Config.Env}}{{if or (eq (index (split . "=") 0) "POSTGRES_USER") (eq (index (split . "=") 0) "POSTGRESQL_USER")}}{{index (split . "=") 1}}{{end}}{{end}}' $container_id)
# 如果环境变量中没有用户名,尝试使用默认用户名
if [ -z "$pg_user" ]; then
# 尝试常见的超级用户名
local common_users=("postgres" "admin" "root" "master")
for user in "${common_users[@]}"; do
if docker exec $container_id psql -U $user -c "SELECT 1" &>/dev/null; then
echo "$user"
return 0
fi
done
# 如果找不到超级用户,询问用户
echo -e "${YELLOW}无法自动检测PostgreSQL超级用户。${NC}"
read -p "请输入PostgreSQL超级用户名: " pg_user
echo "$pg_user"
return 0
else
echo "$pg_user"
return 0
fi
}
# 使用PostgreSQL客户端容器执行命令
run_pg_command() {
local container_id=$1
local command=$2
local db_name=$3
local user=${4:-}
# 如果没有指定用户,尝试检测超级用户
if [ -z "$user" ]; then
if [ -z "$pg_superuser" ]; then
pg_superuser=$(detect_pg_superuser "$container_id")
fi
user=$pg_superuser
fi
# 获取PostgreSQL容器的网络信息
local network=$(docker inspect --format='{{range $k, $v := .NetworkSettings.Networks}}{{$k}}{{end}}' $container_id)
local ip_address=$(docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $container_id)
local port=$(docker inspect --format='{{range $p, $conf := .NetworkSettings.Ports}}{{if eq $p "5432/tcp"}}{{(index $conf 0).HostPort}}{{end}}{{end}}' $container_id)
# 如果没有映射端口,使用默认端口5432
if [ -z "$port" ]; then
port="5432"
fi
# 获取PostgreSQL密码环境变量
local pg_password=$(docker inspect --format='{{range .Config.Env}}{{if or (eq (index (split . "=") 0) "POSTGRES_PASSWORD") (eq (index (split . "=") 0) "POSTGRESQL_PASSWORD")}}{{index (split . "=") 1}}{{end}}{{end}}' $container_id)
# 如果没有找到密码环境变量,询问用户
if [ -z "$pg_password" ]; then
if [ -z "$postgres_password" ]; then
echo -e "${YELLOW}需要PostgreSQL密码来执行管理操作${NC}"
read -s -p "请输入PostgreSQL密码: " postgres_password
echo ""
pg_password=$postgres_password
else
pg_password=$postgres_password
fi
else
postgres_password=$pg_password
fi
# 创建临时脚本
local temp_script=$(mktemp)
echo "#!/bin/bash" > $temp_script
echo "export PGPASSWORD='$pg_password'" >> $temp_script
if [ -n "$db_name" ]; then
echo "psql -h $ip_address -p $port -U $user -d $db_name -c \"$command\"" >> $temp_script
else
echo "psql -h $ip_address -p $port -U $user -c \"$command\"" >> $temp_script
fi
chmod +x $temp_script
# 使用PostgreSQL客户端容器执行命令
local output=$(docker run --rm --network $network -v $temp_script:/tmp/script.sh postgres:14-alpine /tmp/script.sh)
echo "$output"
# 删除临时脚本
rm $temp_script
}
# PostgreSQL菜单
show_postgres_menu() {
# 选择PostgreSQL容器
if [ ${#pg_containers[@]} -gt 1 ]; then
if [ "$CLEAR_SCREEN" = true ]; then
clear
else
echo ""
echo -e "${BLUE}----------------------------------------${NC}"
echo ""
fi
echo -e "${CYAN}========================================"
echo -e " 选择PostgreSQL容器"
echo -e "========================================${NC}"
echo -e "请选择要管理的PostgreSQL容器:"
for i in "${!pg_containers[@]}"; do
if [ "${pg_running_status[$i]}" = true ]; then
echo -e "${GREEN}$((i+1))) ${pg_names[$i]} (${pg_images[$i]}) ${GREEN}[运行中]${NC}"
else
echo -e "${GREEN}$((i+1))) ${pg_names[$i]} (${pg_images[$i]}) ${RED}[已停止]${NC}"
fi
done
echo -e "${YELLOW}$((${#pg_containers[@]}+1))) 返回主菜单${NC}"
echo ""
read -p "请输入选择 [1-$((${#pg_containers[@]}+1))]: " pg_container_choice
if [ "$pg_container_choice" -eq $((${#pg_containers[@]}+1)) ]; then
return
fi
if [ "$pg_container_choice" -lt 1 ] || [ "$pg_container_choice" -gt ${#pg_containers[@]} ]; then
echo -e "${RED}无效选择,请重试${NC}"
sleep 1
show_postgres_menu
return
fi
pg_container_index=$((pg_container_choice-1))
pg_container=${pg_containers[$pg_container_index]}
pg_image=${pg_images[$pg_container_index]}
pg_name=${pg_names[$pg_container_index]}
pg_running=${pg_running_status[$pg_container_index]}
else
pg_container=${pg_containers[0]}
pg_image=${pg_images[0]}
pg_name=${pg_names[0]}
pg_running=${pg_running_status[0]}
fi
if ! check_container_status "$pg_container" "PostgreSQL" "$pg_image" "$pg_running"; then
read -p "按回车键返回主菜单..." temp
return
fi
# 检查容器中是否有psql工具
has_psql=true
if ! check_psql_in_container "$pg_container"; then
has_psql=false
echo -e "${YELLOW}将使用PostgreSQL客户端容器执行命令${NC}"
sleep 2
fi
# 检测PostgreSQL超级用户
if [ -z "$pg_superuser" ]; then
pg_superuser=$(detect_pg_superuser "$pg_container")
echo -e "${GREEN}检测到PostgreSQL超级用户: $pg_superuser${NC}"
sleep 1
fi
# 获取PostgreSQL密码
if [ "$has_psql" = true ]; then
# 如果容器有psql,尝试获取密码环境变量
postgres_password=$(docker inspect --format='{{range .Config.Env}}{{if or (eq (index (split . "=") 0) "POSTGRES_PASSWORD") (eq (index (split . "=") 0) "POSTGRESQL_PASSWORD")}}{{index (split . "=") 1}}{{end}}{{end}}' $pg_container)
# 如果没有找到密码环境变量,询问用户
if [ -z "$postgres_password" ]; then
echo -e "${YELLOW}需要PostgreSQL密码来执行管理操作${NC}"
read -s -p "请输入PostgreSQL密码: " postgres_password
echo ""
fi
fi
while true; do
if [ "$CLEAR_SCREEN" = true ]; then
clear
else
echo ""
echo -e "${BLUE}----------------------------------------${NC}"
echo ""
fi
echo -e "${CYAN}========================================"
echo -e " PostgreSQL 管理菜单"
echo -e "========================================${NC}"
echo -e "当前连接的容器: ${GREEN}${pg_image}${NC} (${YELLOW}${pg_container}${NC})"
echo -e "使用超级用户: ${GREEN}${pg_superuser}${NC}"
echo ""
echo -e "请选择操作:"
echo -e "${GREEN}1) 创建用户和数据库${NC}"
echo -e "${GREEN}2) 查询所有用户和数据库${NC}"
echo -e "${GREEN}3) 删除用户或数据库${NC}"
echo -e "${GREEN}4) 开启PGVector插件${NC}"
echo -e "${YELLOW}5) 返回主菜单${NC}"
echo ""
read -p "请输入选择 [1-5]: " pg_choice
case $pg_choice in
1) create_postgres_user_db ;;
2) list_postgres_users_dbs ;;
3) delete_postgres_user_db ;;
4) enable_pgvector ;;
5) break ;;
*) echo -e "${RED}无效选择,请重试${NC}"
sleep 1 ;;
esac
done
}
# MySQL菜单
show_mysql_menu() {
if ! check_container_status "$mysql_container" "MySQL" "$mysql_image" "$mysql_running"; then
read -p "按回车键返回主菜单..." temp
return
fi
# 第一次进入MySQL菜单,获取root密码
if [ -z "$mysql_root_password" ]; then
# 尝试从环境变量获取密码
mysql_root_password=$(docker inspect --format='{{range .Config.Env}}{{if eq (index (split . "=") 0) "MYSQL_ROOT_PASSWORD"}}{{index (split . "=") 1}}{{end}}{{end}}' $mysql_container)
# 如果没有找到密码环境变量,询问用户
if [ -z "$mysql_root_password" ]; then
echo -e "${YELLOW}需要MySQL root密码来执行管理操作${NC}"
read -s -p "请输入MySQL root密码: " mysql_root_password
echo ""
else
echo -e "${GREEN}已从容器环境变量中获取MySQL root密码${NC}"
sleep 1
fi
# 验证密码是否正确
if ! docker exec $mysql_container mysql -u root -p"$mysql_root_password" -e "SELECT 1" >/dev/null 2>&1; then
echo -e "${RED}密码验证失败,无法连接到MySQL${NC}"
mysql_root_password=""
read -p "按回车键返回主菜单..." temp
return
fi
echo -e "${GREEN}密码验证成功${NC}"
fi
while true; do
if [ "$CLEAR_SCREEN" = true ]; then
clear
else
echo ""
echo -e "${BLUE}----------------------------------------${NC}"
echo ""
fi
echo -e "${CYAN}========================================"
echo -e " MySQL 管理菜单"
echo -e "========================================${NC}"
echo -e "当前连接的容器: ${GREEN}${mysql_image}${NC} (${YELLOW}${mysql_container}${NC})"
echo ""
echo -e "请选择操作:"
echo -e "${GREEN}1) 创建用户和数据库${NC}"
echo -e "${GREEN}2) 查询所有用户和数据库${NC}"
echo -e "${GREEN}3) 删除用户或数据库${NC}"
echo -e "${YELLOW}4) 返回主菜单${NC}"
echo ""
read -p "请输入选择 [1-4]: " mysql_choice
case $mysql_choice in
1) create_mysql_user_db ;;
2) list_mysql_users_dbs ;;
3) delete_mysql_user_db ;;
4) break ;;
*) echo -e "${RED}无效选择,请重试${NC}"
sleep 1 ;;
esac
done
}
# Redis菜单
show_redis_menu() {
if ! check_container_status "$redis_container" "Redis" "$redis_image" "$redis_running"; then
read -p "按回车键返回主菜单..." temp
return
fi
# 检查是否需要Redis密码
if [ -z "$redis_password" ]; then
# 默认假设Redis需要密码
redis_needs_auth=true
# 尝试从环境变量获取密码
redis_password=$(docker inspect --format='{{range .Config.Env}}{{if or (eq (index (split . "=") 0) "REDIS_PASSWORD") (eq (index (split . "=") 0) "REDIS_PASS") (eq (index (split . "=") 0) "REDIS_AUTH")}}{{index (split . "=") 1}}{{end}}{{end}}' $redis_container)
# 如果环境变量中没有密码,询问用户
if [ -z "$redis_password" ]; then
echo -e "${YELLOW}Redis可能需要密码认证${NC}"
read -s -p "请输入Redis密码 (如果不需要密码,直接按回车): " redis_password
echo ""
else
echo -e "${GREEN}已从容器环境变量中获取Redis密码${NC}"
sleep 1
fi
# 测试无密码连接
if [ -z "$redis_password" ] && docker exec $redis_container redis-cli ping >/dev/null 2>&1; then
echo -e "${GREEN}Redis不需要密码认证${NC}"
redis_needs_auth=false
sleep 1
elif [ -n "$redis_password" ]; then
# 验证密码是否正确
if ! docker exec $redis_container redis-cli -a "$redis_password" --no-auth-warning ping >/dev/null 2>&1; then
echo -e "${RED}密码验证失败,无法连接到Redis${NC}"
# 再次尝试获取密码
echo -e "${YELLOW}请再次尝试输入Redis密码${NC}"
read -s -p "请输入Redis密码: " redis_password
echo ""
# 再次验证密码
if ! docker exec $redis_container redis-cli -a "$redis_password" --no-auth-warning ping >/dev/null 2>&1; then
echo -e "${RED}密码验证再次失败${NC}"
# 尝试一些常见的默认密码
echo -e "${YELLOW}尝试常见的默认密码...${NC}"
for default_pass in "redis" "admin" "password" "123456" "root"; do
echo -e "${BLUE}尝试密码: $default_pass${NC}"
if docker exec $redis_container redis-cli -a "$default_pass" --no-auth-warning ping >/dev/null 2>&1; then
redis_password=$default_pass
echo -e "${GREEN}找到有效密码: $default_pass${NC}"
sleep 1
break
fi
done
# 如果仍然失败,提示用户手动输入正确的密码
if ! docker exec $redis_container redis-cli -a "$redis_password" --no-auth-warning ping >/dev/null 2>&1; then
echo -e "${RED}无法自动找到有效的Redis密码${NC}"
echo -e "${YELLOW}请确保输入正确的Redis密码,或者检查Redis配置${NC}"
read -p "按回车键继续,将尝试使用当前密码..." temp
fi
else
echo -e "${GREEN}密码验证成功${NC}"
fi
else
echo -e "${GREEN}密码验证成功${NC}"
fi
else
echo -e "${RED}无法连接到Redis,可能需要密码${NC}"
echo -e "${YELLOW}请输入Redis密码${NC}"
read -s -p "请输入Redis密码: " redis_password
echo ""
# 验证密码
if ! docker exec $redis_container redis-cli -a "$redis_password" --no-auth-warning ping >/dev/null 2>&1; then
echo -e "${RED}密码验证失败${NC}"
echo -e "${YELLOW}将尝试使用当前密码继续操作,如果操作失败,请在设置菜单中重置Redis密码${NC}"
read -p "按回车键继续..." temp
else
echo -e "${GREEN}密码验证成功${NC}"
fi
fi
fi
while true; do
if [ "$CLEAR_SCREEN" = true ]; then
clear
else
echo ""
echo -e "${BLUE}----------------------------------------${NC}"
echo ""
fi
echo -e "${CYAN}========================================"
echo -e " Redis 管理菜单"
echo -e "========================================${NC}"
echo -e "当前连接的容器: ${GREEN}${redis_image}${NC} (${YELLOW}${redis_container}${NC})"
if [ "$redis_needs_auth" = true ] && [ -n "$redis_password" ]; then
echo -e "认证状态: ${GREEN}已认证 (使用密码)${NC}"
elif [ "$redis_needs_auth" = false ]; then
echo -e "认证状态: ${GREEN}无需密码${NC}"
else
echo -e "认证状态: ${RED}未认证${NC}"
fi
echo ""
echo -e "请选择操作:"
echo -e "${GREEN}1) 查看Redis信息${NC}"
echo -e "${GREEN}2) 查看内存使用${NC}"
echo -e "${GREEN}3) 查看键值统计${NC}"
echo -e "${GREEN}4) 设置Redis密码${NC}"
echo -e "${YELLOW}5) 返回主菜单${NC}"
echo ""
read -p "请输入选择 [1-5]: " redis_choice
case $redis_choice in
1) show_redis_info ;;
2) show_redis_memory ;;
3) show_redis_keys ;;
4) set_redis_password ;;
5) break ;;
*) echo -e "${RED}无效选择,请重试${NC}"
sleep 1 ;;
esac
done
}
# Redis功能:设置Redis密码
set_redis_password() {
if [ "$CLEAR_SCREEN" = true ]; then
clear
else
echo ""
echo -e "${BLUE}----------------------------------------${NC}"
echo ""
fi
echo -e "${CYAN}========================================"
echo -e " 设置Redis密码"
echo -e "========================================${NC}"
echo ""
echo -e "${YELLOW}请输入Redis密码:${NC}"
read -s -p "密码: " new_redis_password
echo ""
# 测试新密码
if [ -z "$new_redis_password" ]; then
echo -e "${YELLOW}尝试无密码连接...${NC}"
if docker exec $redis_container redis-cli ping >/dev/null 2>&1; then
echo -e "${GREEN}无密码连接成功${NC}"
redis_password=""
redis_needs_auth=false
else
echo -e "${RED}无密码连接失败,Redis可能需要密码${NC}"
redis_needs_auth=true
fi
else
echo -e "${YELLOW}尝试使用新密码连接...${NC}"
if docker exec $redis_container redis-cli -a "$new_redis_password" --no-auth-warning ping >/dev/null 2>&1; then
echo -e "${GREEN}密码验证成功${NC}"
redis_password=$new_redis_password
redis_needs_auth=true
else
echo -e "${RED}密码验证失败${NC}"
echo -e "${YELLOW}保留原密码设置${NC}"
fi
fi
read -p "按回车键继续..." temp
}
# PostgreSQL功能:创建用户和数据库
create_postgres_user_db() {
if [ "$CLEAR_SCREEN" = true ]; then
clear
else
echo ""
echo -e "${BLUE}----------------------------------------${NC}"
echo ""
fi
echo -e "${CYAN}========================================"
echo -e " 创建PostgreSQL用户和数据库"
echo -e "========================================${NC}"
echo ""
# 获取基础名称
read -p "请输入基础名称 (如输入lobe将创建lobe_user和lobe_db): " base_name
if [ -z "$base_name" ]; then
echo -e "${RED}错误: 名称不能为空${NC}"
read -p "按回车键继续..." temp
return
fi
# 检查名称格式
if ! [[ $base_name =~ ^[a-zA-Z0-9_]+$ ]]; then
echo -e "${RED}错误: 名称只能包含字母、数字和下划线${NC}"
read -p "按回车键继续..." temp
return
fi
user_name="${base_name}_user"
db_name="${base_name}_db"
# 检查用户名是否已存在
echo -e "${BLUE}检查用户是否存在...${NC}"
if [ "$has_psql" = true ]; then
exists=$(docker exec $pg_container psql -U $pg_superuser -tAc "SELECT 1 FROM pg_roles WHERE rolname='$user_name'")
else
exists=$(run_pg_command "$pg_container" "SELECT 1 FROM pg_roles WHERE rolname='$user_name'" "" "$pg_superuser")
fi
if [[ $exists == *"1"* ]]; then
echo -e "${RED}错误: 用户 $user_name 已经存在${NC}"
read -p "按回车键继续..." temp
return
fi
# 检查数据库是否已存在
echo -e "${BLUE}检查数据库是否存在...${NC}"
if [ "$has_psql" = true ]; then
exists=$(docker exec $pg_container psql -U $pg_superuser -tAc "SELECT 1 FROM pg_database WHERE datname='$db_name'")
else
exists=$(run_pg_command "$pg_container" "SELECT 1 FROM pg_database WHERE datname='$db_name'" "" "$pg_superuser")
fi
if [[ $exists == *"1"* ]]; then
echo -e "${RED}错误: 数据库 $db_name 已经存在${NC}"
read -p "按回车键继续..." temp
return
fi
# 获取密码
read -s -p "请设置用户密码: " password
echo ""
read -s -p "确认密码: " password_confirm
echo ""
if [ "$password" != "$password_confirm" ]; then
echo -e "${RED}错误: 两次输入的密码不匹配${NC}"
read -p "按回车键继续..." temp
return
fi
echo -e "${BLUE}创建用户 $user_name...${NC}"
if [ "$has_psql" = true ]; then
if ! docker exec $pg_container psql -U $pg_superuser -c "CREATE USER $user_name WITH PASSWORD '$password';" >/dev/null 2>&1; then
echo -e "${RED}创建用户失败${NC}"
read -p "按回车键继续..." temp
return
fi
else
if ! run_pg_command "$pg_container" "CREATE USER $user_name WITH PASSWORD '$password';" "" "$pg_superuser" >/dev/null 2>&1; then
echo -e "${RED}创建用户失败${NC}"
read -p "按回车键继续..." temp
return
fi
fi
echo -e "${GREEN}成功${NC}"
echo -e "${BLUE}创建数据库 $db_name...${NC}"
if [ "$has_psql" = true ]; then
if ! docker exec $pg_container psql -U $pg_superuser -c "CREATE DATABASE $db_name OWNER $user_name;" >/dev/null 2>&1; then
echo -e "${RED}创建数据库失败${NC}"
echo -e "${YELLOW}正在回滚,删除已创建的用户...${NC}"
docker exec $pg_container psql -U $pg_superuser -c "DROP USER $user_name;" >/dev/null 2>&1
read -p "按回车键继续..." temp
return
fi
else
if ! run_pg_command "$pg_container" "CREATE DATABASE $db_name OWNER $user_name;" "" "$pg_superuser" >/dev/null 2>&1; then
echo -e "${RED}创建数据库失败${NC}"
echo -e "${YELLOW}正在回滚,删除已创建的用户...${NC}"
run_pg_command "$pg_container" "DROP USER $user_name;" "" "$pg_superuser" >/dev/null 2>&1
read -p "按回车键继续..." temp
return
fi
fi
echo -e "${GREEN}成功${NC}"
echo -e "${BLUE}授予用户 $user_name 对数据库 $db_name 的全部权限...${NC}"
if [ "$has_psql" = true ]; then
if ! docker exec $pg_container psql -U $pg_superuser -c "GRANT ALL PRIVILEGES ON DATABASE $db_name TO $user_name;" >/dev/null 2>&1; then
echo -e "${RED}授权失败${NC}"
read -p "按回车键继续..." temp
return
fi
else
if ! run_pg_command "$pg_container" "GRANT ALL PRIVILEGES ON DATABASE $db_name TO $user_name;" "" "$pg_superuser" >/dev/null 2>&1; then
echo -e "${RED}授权失败${NC}"
read -p "按回车键继续..." temp
return
fi
fi
echo -e "${GREEN}成功${NC}"
# 询问是否开启PGVector插件
read -p "是否开启PGVector插件? (y/n): " enable_vector
if [[ $enable_vector == [yY] || $enable_vector == [yY][eE][sS] ]]; then
echo -e "${BLUE}在数据库 $db_name 中开启PGVector插件...${NC}"
if [ "$has_psql" = true ]; then
if ! docker exec $pg_container psql -U $pg_superuser -d $db_name -c "CREATE EXTENSION IF NOT EXISTS vector;" >/dev/null 2>&1; then
echo -e "${RED}执行CREATE EXTENSION命令失败${NC}"
read -p "按回车键继续..." temp
return
fi
# 验证是否启用成功
vector_enabled=$(docker exec $pg_container psql -U $pg_superuser -d $db_name -tAc "SELECT 1 FROM pg_extension WHERE extname='vector'")
if [[ $vector_enabled == *"1"* ]]; then
vector_version=$(docker exec $pg_container psql -U $pg_superuser -d $db_name -tAc "SELECT extversion FROM pg_extension WHERE extname='vector'")
echo -e "${GREEN}PGVector 插件已成功启用 (版本: $vector_version)${NC}"
else
echo -e "${RED}PGVector 插件未能启用,请检查容器配置${NC}"
read -p "按回车键继续..." temp
return
fi
else
if ! run_pg_command "$pg_container" "CREATE EXTENSION IF NOT EXISTS vector;" "$db_name" "$pg_superuser" >/dev/null 2>&1; then
echo -e "${RED}执行CREATE EXTENSION命令失败${NC}"
read -p "按回车键继续..." temp
return
fi
# 验证是否启用成功
vector_enabled=$(run_pg_command "$pg_container" "SELECT 1 FROM pg_extension WHERE extname='vector'" "$db_name" "$pg_superuser")
if [[ $vector_enabled == *"1"* ]]; then
vector_version=$(run_pg_command "$pg_container" "SELECT extversion FROM pg_extension WHERE extname='vector'" "$db_name" "$pg_superuser")
echo -e "${GREEN}PGVector 插件已成功启用 (版本: $vector_version)${NC}"
else
echo -e "${RED}PGVector 插件未能启用,请检查容器配置${NC}"
read -p "按回车键继续..." temp
return
fi
fi
fi
echo -e "${GREEN}操作完成!${NC}"
read -p "按回车键继续..." temp
}
# PostgreSQL功能:查询所有用户和数据库
list_postgres_users_dbs() {
if [ "$CLEAR_SCREEN" = true ]; then
clear
else
echo ""
echo -e "${BLUE}----------------------------------------${NC}"
echo ""
fi
echo -e "${CYAN}========================================"
echo -e " PostgreSQL 用户和数据库列表"
echo -e "========================================${NC}"
echo ""
echo -e "${YELLOW}数据库列表:${NC}"
if [ "$has_psql" = true ]; then
docker exec $pg_container psql -U $pg_superuser -c "SELECT datname AS database_name, pg_size_pretty(pg_database_size(datname)) AS size FROM pg_database WHERE datistemplate = false ORDER BY datname;"
else
run_pg_command "$pg_container" "SELECT datname AS database_name, pg_size_pretty(pg_database_size(datname)) AS size FROM pg_database WHERE datistemplate = false ORDER BY datname;" "" "$pg_superuser"
fi
echo ""
echo -e "${YELLOW}用户列表:${NC}"
if [ "$has_psql" = true ]; then
docker exec $pg_container psql -U $pg_superuser -c "SELECT rolname AS user_name, rolsuper AS is_superuser FROM pg_roles WHERE rolname NOT LIKE 'pg_%' ORDER BY rolname;"
else
run_pg_command "$pg_container" "SELECT rolname AS user_name, rolsuper AS is_superuser FROM pg_roles WHERE rolname NOT LIKE 'pg_%' ORDER BY rolname;" "" "$pg_superuser"
fi
echo ""
echo -e "${YELLOW}用户权限:${NC}"
if [ "$has_psql" = true ]; then
docker exec $pg_container psql -U $pg_superuser -c "SELECT DISTINCT grantee AS user_name, table_catalog AS database_name, privilege_type FROM information_schema.table_privileges WHERE grantee NOT LIKE 'pg_%' ORDER BY grantee, table_catalog;"
else
run_pg_command "$pg_container" "SELECT DISTINCT grantee AS user_name, table_catalog AS database_name, privilege_type FROM information_schema.table_privileges WHERE grantee NOT LIKE 'pg_%' ORDER BY grantee, table_catalog;" "" "$pg_superuser"
fi
read -p "按回车键继续..." temp
}
# PostgreSQL功能:删除用户或数据库
delete_postgres_user_db() {
if [ "$CLEAR_SCREEN" = true ]; then
clear
else
echo ""
echo -e "${BLUE}----------------------------------------${NC}"
echo ""
fi
echo -e "${CYAN}========================================"
echo -e " 删除PostgreSQL用户或数据库"
echo -e "========================================${NC}"
echo ""
echo -e "请选择要删除的对象:"
echo -e "${GREEN}1) 用户${NC}"
echo -e "${GREEN}2) 数据库${NC}"
echo -e "${YELLOW}3) 返回上级菜单${NC}"
echo ""
read -p "请输入选择 [1-3]: " delete_choice
case $delete_choice in
1) # 删除用户
echo -e "${YELLOW}当前PostgreSQL用户列表:${NC}"
if [ "$has_psql" = true ]; then
docker exec $pg_container psql -U $pg_superuser -c "SELECT rolname AS user_name FROM pg_roles WHERE rolname NOT LIKE 'pg_%' AND rolname != '$pg_superuser' ORDER BY rolname;"
else
run_pg_command "$pg_container" "SELECT rolname AS user_name FROM pg_roles WHERE rolname NOT LIKE 'pg_%' AND rolname != '$pg_superuser' ORDER BY rolname;" "" "$pg_superuser"
fi
echo ""
read -p "请输入要删除的用户名: " user_name
if [ -z "$user_name" ]; then
echo -e "${RED}错误: 用户名不能为空${NC}"
read -p "按回车键继续..." temp
return
fi
# 检查用户是否存在
if [ "$has_psql" = true ]; then
exists=$(docker exec $pg_container psql -U $pg_superuser -tAc "SELECT 1 FROM pg_roles WHERE rolname='$user_name'")
else
exists=$(run_pg_command "$pg_container" "SELECT 1 FROM pg_roles WHERE rolname='$user_name'" "" "$pg_superuser")
fi
if ! [[ $exists == *"1"* ]]; then
echo -e "${RED}错误: 用户 $user_name 不存在${NC}"
read -p "按回车键继续..." temp
return
fi
# 检查关联的数据库
if [ "$has_psql" = true ]; then
associated_db=$(docker exec $pg_container psql -U $pg_superuser -tAc "SELECT datname FROM pg_database WHERE datdba = (SELECT oid FROM pg_roles WHERE rolname='$user_name') LIMIT 1")
else
associated_db=$(run_pg_command "$pg_container" "SELECT datname FROM pg_database WHERE datdba = (SELECT oid FROM pg_roles WHERE rolname='$user_name') LIMIT 1" "" "$pg_superuser")
fi
if [ -n "$associated_db" ]; then
echo -e "${YELLOW}检测到关联的数据库: $associated_db${NC}"
read -p "是否同时删除关联的数据库? (y/n): " delete_db
if [[ $delete_db == [yY] || $delete_db == [yY][eE][sS] ]]; then
echo -e "${BLUE}删除数据库 $associated_db...${NC}"
if [ "$has_psql" = true ]; then
if ! docker exec $pg_container psql -U $pg_superuser -c "DROP DATABASE $associated_db;" >/dev/null 2>&1; then
echo -e "${RED}删除数据库失败${NC}"
read -p "按回车键继续..." temp
return
fi
else
if ! run_pg_command "$pg_container" "DROP DATABASE $associated_db;" "" "$pg_superuser" >/dev/null 2>&1; then
echo -e "${RED}删除数据库失败${NC}"
read -p "按回车键继续..." temp
return
fi
fi
echo -e "${GREEN}成功${NC}"
fi
fi
echo -e "${BLUE}删除用户 $user_name...${NC}"
if [ "$has_psql" = true ]; then
if ! docker exec $pg_container psql -U $pg_superuser -c "DROP USER $user_name;" >/dev/null 2>&1; then
echo -e "${RED}删除用户失败${NC}"
read -p "按回车键继续..." temp
return
fi
else
if ! run_pg_command "$pg_container" "DROP USER $user_name;" "" "$pg_superuser" >/dev/null 2>&1; then
echo -e "${RED}删除用户失败${NC}"
read -p "按回车键继续..." temp
return
fi
fi
echo -e "${GREEN}成功${NC}"
;;
2) # 删除数据库
echo -e "${YELLOW}当前PostgreSQL数据库列表:${NC}"
if [ "$has_psql" = true ]; then
docker exec $pg_container psql -U $pg_superuser -c "SELECT datname AS database_name FROM pg_database WHERE datistemplate = false AND datname != 'postgres' ORDER BY datname;"
else
run_pg_command "$pg_container" "SELECT datname AS database_name FROM pg_database WHERE datistemplate = false AND datname != 'postgres' ORDER BY datname;" "" "$pg_superuser"
fi
echo ""
read -p "请输入要删除的数据库名: " db_name
if [ -z "$db_name" ]; then
echo -e "${RED}错误: 数据库名不能为空${NC}"
read -p "按回车键继续..." temp
return
fi
# 检查数据库是否存在
if [ "$has_psql" = true ]; then
exists=$(docker exec $pg_container psql -U $pg_superuser -tAc "SELECT 1 FROM pg_database WHERE datname='$db_name'")
else
exists=$(run_pg_command "$pg_container" "SELECT 1 FROM pg_database WHERE datname='$db_name'" "" "$pg_superuser")
fi
if ! [[ $exists == *"1"* ]]; then
echo -e "${RED}错误: 数据库 $db_name 不存在${NC}"
read -p "按回车键继续..." temp
return
fi
# 检查拥有该数据库的用户
if [ "$has_psql" = true ]; then
owner=$(docker exec $pg_container psql -U $pg_superuser -tAc "SELECT rolname FROM pg_roles WHERE oid = (SELECT datdba FROM pg_database WHERE datname='$db_name')")
else
owner=$(run_pg_command "$pg_container" "SELECT rolname FROM pg_roles WHERE oid = (SELECT datdba FROM pg_database WHERE datname='$db_name')" "" "$pg_superuser")
fi
if [ "$owner" != "$pg_superuser" ]; then
echo -e "${YELLOW}检测到数据库所有者: $owner${NC}"
read -p "是否同时删除数据库所有者? (y/n): " delete_owner
if [[ $delete_owner == [yY] || $delete_owner == [yY][eE][sS] ]]; then
# 先删数据库再删用户
delete_owner_later=true
fi
fi
echo -e "${BLUE}删除数据库 $db_name...${NC}"
if [ "$has_psql" = true ]; then
if ! docker exec $pg_container psql -U $pg_superuser -c "DROP DATABASE $db_name;" >/dev/null 2>&1; then
echo -e "${RED}删除数据库失败${NC}"
read -p "按回车键继续..." temp
return
fi
else
if ! run_pg_command "$pg_container" "DROP DATABASE $db_name;" "" "$pg_superuser" >/dev/null 2>&1; then
echo -e "${RED}删除数据库失败${NC}"
read -p "按回车键继续..." temp
return
fi
fi
echo -e "${GREEN}成功${NC}"
if [ "$delete_owner_later" = true ]; then
echo -e "${BLUE}删除用户 $owner...${NC}"
if [ "$has_psql" = true ]; then
if ! docker exec $pg_container psql -U $pg_superuser -c "DROP USER $owner;" >/dev/null 2>&1; then
echo -e "${RED}删除用户失败${NC}"
read -p "按回车键继续..." temp
return
fi
else
if ! run_pg_command "$pg_container" "DROP USER $owner;" "" "$pg_superuser" >/dev/null 2>&1; then
echo -e "${RED}删除用户失败${NC}"
read -p "按回车键继续..." temp
return
fi
fi
echo -e "${GREEN}成功${NC}"
fi
;;
3) return ;;
*) echo -e "${RED}无效选择,请重试${NC}"
sleep 1
delete_postgres_user_db
;;
esac
echo -e "${GREEN}操作完成!${NC}"
read -p "按回车键继续..." temp
}
# PostgreSQL功能:开启PGVector插件
enable_pgvector() {
if [ "$CLEAR_SCREEN" = true ]; then
clear
else
echo ""
echo -e "${BLUE}----------------------------------------${NC}"
echo ""
fi
echo -e "${CYAN}========================================"
echo -e " 开启PostgreSQL PGVector插件"
echo -e "========================================${NC}"
echo ""
echo -e "${YELLOW}可用的数据库列表:${NC}"
if [ "$has_psql" = true ]; then
docker exec $pg_container psql -U $pg_superuser -c "SELECT datname AS database_name FROM pg_database WHERE datistemplate = false AND datname != 'postgres' ORDER BY datname;"
else
run_pg_command "$pg_container" "SELECT datname AS database_name FROM pg_database WHERE datistemplate = false AND datname != 'postgres' ORDER BY datname;" "" "$pg_superuser"
fi
echo ""
read -p "请输入要开启PGVector插件的数据库名: " db_name
if [ -z "$db_name" ]; then
echo -e "${RED}错误: 数据库名不能为空${NC}"
read -p "按回车键继续..." temp
return
fi
# 检查数据库是否存在
if [ "$has_psql" = true ]; then
exists=$(docker exec $pg_container psql -U $pg_superuser -tAc "SELECT 1 FROM pg_database WHERE datname='$db_name'")
else
exists=$(run_pg_command "$pg_container" "SELECT 1 FROM pg_database WHERE datname='$db_name'" "" "$pg_superuser")
fi
if ! [[ $exists == *"1"* ]]; then
echo -e "${RED}错误: 数据库 $db_name 不存在${NC}"
read -p "按回车键继续..." temp
return
fi
echo -e "${BLUE}在数据库 $db_name 中开启PGVector插件...${NC}"
if [ "$has_psql" = true ]; then
if ! docker exec $pg_container psql -U $pg_superuser -d $db_name -c "CREATE EXTENSION IF NOT EXISTS vector;" >/dev/null 2>&1; then
echo -e "${RED}执行CREATE EXTENSION命令失败${NC}"
read -p "按回车键继续..." temp
return
fi
# 验证是否启用成功
vector_enabled=$(docker exec $pg_container psql -U $pg_superuser -d $db_name -tAc "SELECT 1 FROM pg_extension WHERE extname='vector'")
if [[ $vector_enabled == *"1"* ]]; then
vector_version=$(docker exec $pg_container psql -U $pg_superuser -d $db_name -tAc "SELECT extversion FROM pg_extension WHERE extname='vector'")
echo -e "${GREEN}PGVector 插件已成功启用 (版本: $vector_version)${NC}"
else
echo -e "${RED}PGVector 插件未能启用,请检查容器配置${NC}"
read -p "按回车键继续..." temp
return
fi
else
if ! run_pg_command "$pg_container" "CREATE EXTENSION IF NOT EXISTS vector;" "$db_name" "$pg_superuser" >/dev/null 2>&1; then
echo -e "${RED}执行CREATE EXTENSION命令失败${NC}"
read -p "按回车键继续..." temp
return
fi
# 验证是否启用成功
vector_enabled=$(run_pg_command "$pg_container" "SELECT 1 FROM pg_extension WHERE extname='vector'" "$db_name" "$pg_superuser")
if [[ $vector_enabled == *"1"* ]]; then
vector_version=$(run_pg_command "$pg_container" "SELECT extversion FROM pg_extension WHERE extname='vector'" "$db_name" "$pg_superuser")
echo -e "${GREEN}PGVector 插件已成功启用 (版本: $vector_version)${NC}"
else
echo -e "${RED}PGVector 插件未能启用,请检查容器配置${NC}"
read -p "按回车键继续..." temp
return
fi
fi
echo -e "${GREEN}操作完成!${NC}"
read -p "按回车键继续..." temp
}
# MySQL功能:创建用户和数据库
create_mysql_user_db() {
if [ "$CLEAR_SCREEN" = true ]; then
clear
else
echo ""
echo -e "${BLUE}----------------------------------------${NC}"
echo ""
fi
echo -e "${CYAN}========================================"
echo -e " 创建MySQL用户和数据库"
echo -e "========================================${NC}"
echo ""
# 获取基础名称
read -p "请输入基础名称 (如输入lobe将创建lobe_user和lobe_db): " base_name
if [ -z "$base_name" ]; then
echo -e "${RED}错误: 名称不能为空${NC}"
read -p "按回车键继续..." temp
return
fi
# 检查名称格式
if ! [[ $base_name =~ ^[a-zA-Z0-9_]+$ ]]; then
echo -e "${RED}错误: 名称只能包含字母、数字和下划线${NC}"
read -p "按回车键继续..." temp
return
fi
user_name="${base_name}_user"
db_name="${base_name}_db"
# 检查用户名是否已存在
if docker exec $mysql_container mysql -u root -p"$mysql_root_password" -e "SELECT User FROM mysql.user WHERE User='$user_name';" 2>/dev/null | grep -q "$user_name"; then
echo -e "${RED}错误: 用户 $user_name 已经存在${NC}"
read -p "按回车键继续..." temp
return
fi
# 检查数据库是否已存在
if docker exec $mysql_container mysql -u root -p"$mysql_root_password" -e "SHOW DATABASES LIKE '$db_name';" 2>/dev/null | grep -q "$db_name"; then
echo -e "${RED}错误: 数据库 $db_name 已经存在${NC}"
read -p "按回车键继续..." temp
return
fi
# 获取密码
read -s -p "请设置用户密码: " password
echo ""
read -s -p "确认密码: " password_confirm
echo ""
if [ "$password" != "$password_confirm" ]; then
echo -e "${RED}错误: 两次输入的密码不匹配${NC}"
read -p "按回车键继续..." temp
return
fi
# 检测MySQL版本
mysql_version=$(docker exec $mysql_container mysql -u root -p"$mysql_root_password" -e "SELECT VERSION();" 2>/dev/null | grep -v "VERSION()")
mysql_major_version=$(echo $mysql_version | cut -d. -f1)
echo -e "${BLUE}创建数据库 $db_name 并支持emoji (utf8mb4)...${NC}"
if ! docker exec $mysql_container mysql -u root -p"$mysql_root_password" -e "CREATE DATABASE $db_name CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;" >/dev/null 2>&1; then
echo -e "${RED}创建数据库失败${NC}"
read -p "按回车键继续..." temp
return
fi
echo -e "${GREEN}成功${NC}"
echo -e "${BLUE}创建用户 $user_name...${NC}"
if [ "$mysql_major_version" -ge "8" ]; then
# MySQL 8.0+ 语法
if ! docker exec $mysql_container mysql -u root -p"$mysql_root_password" -e "CREATE USER '$user_name'@'%' IDENTIFIED BY '$password';" >/dev/null 2>&1; then
echo -e "${RED}创建用户失败${NC}"
echo -e "${YELLOW}正在回滚,删除已创建的数据库...${NC}"
docker exec $mysql_container mysql -u root -p"$mysql_root_password" -e "DROP DATABASE IF EXISTS $db_name;" >/dev/null 2>&1
read -p "按回车键继续..." temp
return
fi
else
# MySQL 5.7 语法
if ! docker exec $mysql_container mysql -u root -p"$mysql_root_password" -e "CREATE USER '$user_name'@'%' IDENTIFIED BY '$password';" >/dev/null 2>&1; then
echo -e "${RED}创建用户失败${NC}"
echo -e "${YELLOW}正在回滚,删除已创建的数据库...${NC}"
docker exec $mysql_container mysql -u root -p"$mysql_root_password" -e "DROP DATABASE IF EXISTS $db_name;" >/dev/null 2>&1
read -p "按回车键继续..." temp
return
fi
fi
echo -e "${GREEN}成功${NC}"
echo -e "${BLUE}授予用户 $user_name 对数据库 $db_name 的全部权限...${NC}"
if ! docker exec $mysql_container mysql -u root -p"$mysql_root_password" -e "GRANT ALL PRIVILEGES ON $db_name.* TO '$user_name'@'%';" >/dev/null 2>&1; then
echo -e "${RED}授权失败${NC}"
read -p "按回车键继续..." temp
return
fi
echo -e "${BLUE}刷新权限...${NC}"
if ! docker exec $mysql_container mysql -u root -p"$mysql_root_password" -e "FLUSH PRIVILEGES;" >/dev/null 2>&1; then
echo -e "${RED}刷新权限失败${NC}"
read -p "按回车键继续..." temp
return
fi
echo -e "${GREEN}成功${NC}"
echo -e "${GREEN}操作完成!${NC}"
read -p "按回车键继续..." temp
}
# MySQL功能:查询所有用户和数据库
list_mysql_users_dbs() {
if [ "$CLEAR_SCREEN" = true ]; then
clear
else
echo ""
echo -e "${BLUE}----------------------------------------${NC}"
echo ""
fi
echo -e "${CYAN}========================================"
echo -e " MySQL 用户和数据库列表"
echo -e "========================================${NC}"
echo ""
echo -e "${YELLOW}数据库列表:${NC}"
docker exec $mysql_container mysql -u root -p"$mysql_root_password" -e "SELECT table_schema AS database_name, ROUND(SUM(data_length + index_length) / 1024 / 1024, 2) AS size_mb FROM information_schema.tables GROUP BY table_schema ORDER BY table_schema;"
echo ""
echo -e "${YELLOW}用户列表:${NC}"
docker exec $mysql_container mysql -u root -p"$mysql_root_password" -e "SELECT User, Host FROM mysql.user ORDER BY User;"
echo ""
echo -e "${YELLOW}用户权限:${NC}"
docker exec $mysql_container mysql -u root -p"$mysql_root_password" -e "SELECT User, Host, Db, Select_priv, Insert_priv, Update_priv, Delete_priv FROM mysql.db ORDER BY User, Db;"
read -p "按回车键继续..." temp
}
# MySQL功能:删除用户或数据库
delete_mysql_user_db() {
if [ "$CLEAR_SCREEN" = true ]; then
clear
else
echo ""
echo -e "${BLUE}----------------------------------------${NC}"
echo ""
fi
echo -e "${CYAN}========================================"
echo -e " 删除MySQL用户或数据库"
echo -e "========================================${NC}"
echo ""
echo -e "请选择要删除的对象:"
echo -e "${GREEN}1) 用户${NC}"
echo -e "${GREEN}2) 数据库${NC}"
echo -e "${YELLOW}3) 返回上级菜单${NC}"
echo ""
read -p "请输入选择 [1-3]: " delete_choice
case $delete_choice in
1) # 删除用户
echo -e "${YELLOW}当前MySQL用户列表:${NC}"
docker exec $mysql_container mysql -u root -p"$mysql_root_password" -e "SELECT User, Host FROM mysql.user WHERE User NOT IN ('root', 'mysql.sys', 'mysql.session', 'mysql.infoschema') ORDER BY User;"
echo ""
read -p "请输入要删除的用户名: " user_name
if [ -z "$user_name" ]; then
echo -e "${RED}错误: 用户名不能为空${NC}"
read -p "按回车键继续..." temp
return
fi
# 检查用户是否存在
if ! docker exec $mysql_container mysql -u root -p"$mysql_root_password" -e "SELECT User FROM mysql.user WHERE User='$user_name';" 2>/dev/null | grep -q "$user_name"; then
echo -e "${RED}错误: 用户 $user_name 不存在${NC}"
read -p "按回车键继续..." temp
return
fi
# 检查关联的数据库
associated_db=$(docker exec $mysql_container mysql -u root -p"$mysql_root_password" -e "SELECT Db FROM mysql.db WHERE User='$user_name' LIMIT 1;" 2>/dev/null | grep -v "Db")
if [ -n "$associated_db" ]; then
echo -e "${YELLOW}检测到关联的数据库: $associated_db${NC}"
read -p "是否同时删除关联的数据库? (y/n): " delete_db
if [[ $delete_db == [yY] || $delete_db == [yY][eE][sS] ]]; then
echo -e "${BLUE}删除数据库 $associated_db...${NC}"
if ! docker exec $mysql_container mysql -u root -p"$mysql_root_password" -e "DROP DATABASE $associated_db;" >/dev/null 2>&1; then
echo -e "${RED}删除数据库失败${NC}"
read -p "按回车键继续..." temp
return
fi
echo -e "${GREEN}成功${NC}"
fi
fi
echo -e "${BLUE}删除用户 $user_name...${NC}"
if ! docker exec $mysql_container mysql -u root -p"$mysql_root_password" -e "DROP USER '$user_name'@'%';" >/dev/null 2>&1; then
echo -e "${RED}删除用户失败${NC}"
read -p "按回车键继续..." temp
return
fi
echo -e "${GREEN}成功${NC}"
echo -e "${BLUE}刷新权限...${NC}"
docker exec $mysql_container mysql -u root -p"$mysql_root_password" -e "FLUSH PRIVILEGES;" >/dev/null 2>&1
echo -e "${GREEN}成功${NC}"
;;
2) # 删除数据库
echo -e "${YELLOW}当前MySQL数据库列表:${NC}"
docker exec $mysql_container mysql -u root -p"$mysql_root_password" -e "SHOW DATABASES WHERE \`Database\` NOT IN ('information_schema', 'mysql', 'performance_schema', 'sys');"
echo ""
read -p "请输入要删除的数据库名: " db_name
if [ -z "$db_name" ]; then
echo -e "${RED}错误: 数据库名不能为空${NC}"
read -p "按回车键继续..." temp
return
fi
# 检查数据库是否存在
if ! docker exec $mysql_container mysql -u root -p"$mysql_root_password" -e "SHOW DATABASES LIKE '$db_name';" 2>/dev/null | grep -q "$db_name"; then
echo -e "${RED}错误: 数据库 $db_name 不存在${NC}"
read -p "按回车键继续..." temp
return
fi
# 检查拥有该数据库权限的用户
users_with_access=$(docker exec $mysql_container mysql -u root -p"$mysql_root_password" -e "SELECT User FROM mysql.db WHERE Db='$db_name';" 2>/dev/null | grep -v "User")
if [ -n "$users_with_access" ]; then
echo -e "${YELLOW}检测到以下用户拥有该数据库的权限:${NC}"
echo "$users_with_access"
read -p "是否同时删除这些用户? (y/n): " delete_users
if [[ $delete_users == [yY] || $delete_users == [yY][eE][sS] ]]; then
# 先删数据库再删用户
delete_users_later=true
fi
fi
echo -e "${BLUE}删除数据库 $db_name...${NC}"
if ! docker exec $mysql_container mysql -u root -p"$mysql_root_password" -e "DROP DATABASE $db_name;" >/dev/null 2>&1; then
echo -e "${RED}删除数据库失败${NC}"
read -p "按回车键继续..." temp
return
fi
echo -e "${GREEN}成功${NC}"
if [ "$delete_users_later" = true ]; then
for user in $users_with_access; do
echo -e "${BLUE}删除用户 $user...${NC}"
if ! docker exec $mysql_container mysql -u root -p"$mysql_root_password" -e "DROP USER '$user'@'%';" >/dev/null 2>&1; then
echo -e "${RED}删除用户 $user 失败${NC}"
else
echo -e "${GREEN}成功${NC}"
fi
done
echo -e "${BLUE}刷新权限...${NC}"
docker exec $mysql_container mysql -u root -p"$mysql_root_password" -e "FLUSH PRIVILEGES;" >/dev/null 2>&1
echo -e "${GREEN}成功${NC}"
fi
;;
3) return ;;
*) echo -e "${RED}无效选择,请重试${NC}"
sleep 1
delete_mysql_user_db
;;
esac
echo -e "${GREEN}操作完成!${NC}"
read -p "按回车键继续..." temp
}
# Redis功能:查看Redis信息
show_redis_info() {
if [ "$CLEAR_SCREEN" = true ]; then
clear
else
echo ""
echo -e "${BLUE}----------------------------------------${NC}"
echo ""
fi
echo -e "${CYAN}========================================"
echo -e " Redis 服务器信息"
echo -e "========================================${NC}"
echo ""
echo -e "${YELLOW}Redis服务器信息:${NC}"
if [ -n "$redis_password" ]; then
docker exec $redis_container redis-cli -a "$redis_password" --no-auth-warning info server | grep -v "#"
else
docker exec $redis_container redis-cli info server | grep -v "#"
fi
echo ""
echo -e "${YELLOW}Redis客户端连接信息:${NC}"
if [ -n "$redis_password" ]; then
docker exec $redis_container redis-cli -a "$redis_password" --no-auth-warning info clients | grep -v "#"
else
docker exec $redis_container redis-cli info clients | grep -v "#"
fi
echo ""
echo -e "${YELLOW}Redis统计信息:${NC}"
if [ -n "$redis_password" ]; then
docker exec $redis_container redis-cli -a "$redis_password" --no-auth-warning info stats | grep -v "#" | head -15
else
docker exec $redis_container redis-cli info stats | grep -v "#" | head -15
fi
echo ""
echo -e "${YELLOW}Redis持久化信息:${NC}"
if [ -n "$redis_password" ]; then
docker exec $redis_container redis-cli -a "$redis_password" --no-auth-warning info persistence | grep -v "#"
else
docker exec $redis_container redis-cli info persistence | grep -v "#"
fi
read -p "按回车键继续..." temp
}
# Redis功能:查看内存使用
show_redis_memory() {
if [ "$CLEAR_SCREEN" = true ]; then
clear
else
echo ""
echo -e "${BLUE}----------------------------------------${NC}"
echo ""
fi
echo -e "${CYAN}========================================"
echo -e " Redis 内存使用情况"
echo -e "========================================${NC}"
echo ""
echo -e "${YELLOW}内存使用概览:${NC}"
if [ -n "$redis_password" ]; then
docker exec $redis_container redis-cli -a "$redis_password" --no-auth-warning info memory | grep -v "#"
else
docker exec $redis_container redis-cli info memory | grep -v "#"
fi
echo ""
echo -e "${YELLOW}内存使用详情:${NC}"
if [ -n "$redis_password" ]; then
docker exec $redis_container redis-cli -a "$redis_password" --no-auth-warning memory stats | head -20
else
docker exec $redis_container redis-cli memory stats | head -20
fi
echo ""
echo -e "${YELLOW}数据库键值统计:${NC}"
if [ -n "$redis_password" ]; then
docker exec $redis_container redis-cli -a "$redis_password" --no-auth-warning info keyspace | grep -v "#"
else
docker exec $redis_container redis-cli info keyspace | grep -v "#"
fi
read -p "按回车键继续..." temp
}
# Redis功能:查看键值统计
show_redis_keys() {
if [ "$CLEAR_SCREEN" = true ]; then
clear
else
echo ""
echo -e "${BLUE}----------------------------------------${NC}"
echo ""
fi
echo -e "${CYAN}========================================"
echo -e " Redis 键值统计"
echo -e "========================================${NC}"
echo ""
echo -e "${YELLOW}数据库键值统计:${NC}"
if [ -n "$redis_password" ]; then
docker exec $redis_container redis-cli -a "$redis_password" --no-auth-warning info keyspace | grep -v "#"
else
docker exec $redis_container redis-cli info keyspace | grep -v "#"
fi
echo ""
echo -e "${YELLOW}键值类型分布:${NC}"
if [ -n "$redis_password" ]; then
# 获取所有数据库
dbs=$(docker exec $redis_container redis-cli -a "$redis_password" --no-auth-warning info keyspace | grep -v "#" | grep "^db" | cut -d: -f1)
if [ -z "$dbs" ]; then
echo -e "${YELLOW}没有找到任何数据库或键值${NC}"
else
for db in $dbs; do
echo -e "${BLUE}数据库 $db:${NC}"
# 选择数据库并统计键类型
docker exec $redis_container redis-cli -a "$redis_password" --no-auth-warning -n ${db#db} info keyspace | grep -v "#"
# 使用 SCAN 命令统计部分键的类型(避免 KEYS 命令对大数据库的影响)
echo -e "${GREEN}键类型样本统计 (前100个键):${NC}"
docker exec $redis_container redis-cli -a "$redis_password" --no-auth-warning -n ${db#db} --scan --count 100 | while read -r key; do
type=$(docker exec $redis_container redis-cli -a "$redis_password" --no-auth-warning -n ${db#db} type "$key")
echo "键: $key -> 类型: $type"
done | sort | uniq -c | sort -nr
done
fi
else
dbs=$(docker exec $redis_container redis-cli info keyspace | grep -v "#" | grep "^db" | cut -d: -f1)
if [ -z "$dbs" ]; then
echo -e "${YELLOW}没有找到任何数据库或键值${NC}"
else
for db in $dbs; do
echo -e "${BLUE}数据库 $db:${NC}"
docker exec $redis_container redis-cli -n ${db#db} info keyspace | grep -v "#"
echo -e "${GREEN}键类型样本统计 (前100个键):${NC}"
docker exec $redis_container redis-cli -n ${db#db} --scan --count 100 | while read -r key; do
type=$(docker exec $redis_container redis-cli -n ${db#db} type "$key")
echo "键: $key -> 类型: $type"
done | sort | uniq -c | sort -nr
done
fi
fi
read -p "按回车键继续..." temp
}
# 主循环
main() {
check_docker
while true; do
find_containers
show_main_menu
if [ -z "$main_choice" ] || ! [[ "$main_choice" =~ ^[0-9]+$ ]]; then
echo -e "${RED}无效选择,请重试${NC}"
sleep 1
continue
fi
if [ "$main_choice" -eq "$exit_option" ]; then
echo -e "${GREEN}感谢使用容器数据库管理工具,再见!${NC}"
exit 0
elif [ "$main_choice" -eq "$settings_option" ]; then
show_settings_menu
elif [ "$main_choice" -le "$pg_count" ] && [ "$main_choice" -ge 1 ]; then
show_postgres_menu
elif [ "$main_choice" -eq "$mysql_option" ] && [ -n "$mysql_container" ]; then
show_mysql_menu
elif [ "$main_choice" -eq "$redis_option" ] && [ -n "$redis_container" ]; then
show_redis_menu
else
echo -e "${RED}无效选择,请重试${NC}"
sleep 1
fi
done
}
# 启动脚本
main
0