Unix Shell脚本无法读取config.txt中多组数据库连接信息的问题
问题:Shell脚本重复使用第二组数据库连接执行SQL
需求与环境
- 文件夹结构:
Main folder Folder1/first.sql Folder2/second.sql config.txt
config.txt包含两组数据库连接信息:
DB_USER:FIRST DB_PASSWORD:password DB_HOST:10.192.1.162 DB_PORT:1592 DB_SERVICE_NAME:abc_1 DB_USER:SECOND DB_PASSWORD:password DB_HOST:10.192.1.162 DB_PORT:1592 DB_SERVICE_NAME:abd_1
- 执行原脚本时,仅读取第二组连接信息,并用该连接执行两次所有SQL脚本。
问题根源
- 变量覆盖:原脚本直接
source config.txt,但文件中两组配置的变量名完全重复,source后第二组变量会直接覆盖第一组,导致后续逻辑只能使用最后一组的值。 - 循环逻辑错误:
find . -maxdepth 2 -name "config.txt"只会找到主目录下的一个配置文件,循环仅执行一次,但切换目录后会遍历所有子文件夹的SQL,最终用同一连接执行了所有脚本。 - 无环境隔离:没有为每组连接创建独立的变量环境,导致全局变量被污染。
修复方案
修复后的脚本
set +x # 切换到主工作目录 cd /home/Test || exit 1 # 按空行分割config.txt中的每组数据库配置 awk 'BEGIN {RS=""; FS="\n"} {print $0}' config.txt | while read -r config_block; do # 从当前配置块提取变量 DB_USER=$(echo "$config_block" | grep 'DB_USER:' | cut -d':' -f2) DB_PASSWORD=$(echo "$config_block" | grep 'DB_PASSWORD:' | cut -d':' -f2) DB_SERVICE_NAME=$(echo "$config_block" | grep 'DB_SERVICE_NAME:' | cut -d':' -f2) echo "当前使用数据库用户: $DB_USER" echo "目标服务名: $DB_SERVICE_NAME" # 关联数据库用户与对应文件夹 case "$DB_USER" in FIRST) target_folder="./Folder1" ;; SECOND) target_folder="./Folder2" ;; *) echo "未知用户 $DB_USER,跳过"; continue ;; esac # 进入目标文件夹 cd "$target_folder" || { echo "无法访问文件夹 $target_folder"; exit 1; } echo "当前工作目录: $(pwd)" echo "待执行SQL文件:" find . -name "*.sql" # 遍历并执行所有SQL脚本 find . -name "*.sql" | while IFS= read -r sql_file; do echo "正在执行: $sql_file" sqlplus -s "$DB_USER/$DB_PASSWORD@$DB_SERVICE_NAME" < "$sql_file" > /dev/null if [ $? -ne 0 ]; then echo "执行 $sql_file 失败" exit 1 fi done # 返回主目录处理下一组配置 cd /home/Test || exit 1 done echo "所有SQL脚本执行完成" exit 0
关键改进点
- 用
awk按空行分割配置块,避免变量覆盖,每组配置单独处理。 - 不再使用
source,而是从配置块中提取变量,保证每组配置的环境独立。 - 通过
case语句将数据库用户与对应的子文件夹绑定,确保每组连接只执行对应目录下的SQL。 - 添加目录切换失败的容错处理,避免脚本异常退出。
内容的提问来源于stack exchange,提问作者Vicky
相关产品推荐
相关产品推荐

