我试图从shell脚本实现以下要求,但没有得到适当的输出。
要求:我有一个主文件夹,其中包括两个子文件夹和子文件夹内,我有SQL脚本,我需要在各自的数据库执行。我在config.txt文件中给出了所有数据库连接的详细信息。下面是文件夹结构
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
shell 脚本
set +x
#change directory to the main folder
cd /home/Test
# Loop through all config files in the main folder
for config_file in $(find . -maxdepth 2 -name "config.txt"); do
source "$config_file"
echo "DB_USER:$DB_USER"
echo "DB_PASSWORD:$DB_PASSWORD"
echo "DB_SERVICE_NAME:$DB_SERVICE_NAME"
# Change directory to the folder containing the SQL scripts
folder=$(dirname "$config_file")
cd "$folder"
#echo "DB_USER:$DB_USER"
#echo "DB_PASSWORD:$DB_PASSWORD"
#echo "DB_SERVICE_NAME:$DB_SERVICE_NAME"
echo "Current directory: $(pwd)"
echo "List of SQL files:"
find . -name "*.sql"
echo "Processing SQL files. Please wait.."
# Loop through all SQL scripts in the current folder and its subfolders
sql_files=$(find . -name "*.sql")
if [ -n "$sql_files" ]; then
while IFS= read -r file; do
echo "Executing SQL script $file"
echo "DB_USER: $DB_USER"
echo "DB_SERVICE_NAME:$DB_SERVICE_NAME"
sqlplus -s "$DB_USER/$DB_PASSWORD@$DB_SERVICE_NAME" < "$file" > /dev/null
if [ $? -ne 0 ]; then
echo "Error executing $file"
exit 1
fi
done <<< "$sql_files"
else
echo "No SQL files found in the current directory"
fi
# Change back to the main folder
cd ..
done
echo "All SQL scripts executed successfully for all connections"
exit 0
问题:
当我尝试执行上面的shell脚本时,它只需要第二个DB连接的详细信息,并执行SQL脚本两次。
SQL脚本
第一个SQL文件
create table test(colA number,colB number);
insert into test values(1,2);
commit;
GRANT SELECT ON FIRST.TEST TO READ_ROLE;
第二个SQL文件
create table test(colA number,colB number);
insert into test values(1,2);
commit;
GRANT SELECT ON SECOND.TEST TO READ_ROLE;
1条答案
按热度按时间ljsrvy3e1#
这里的问题是,您将两个SQL配置数据存储在一个具有相同变量名的
config.txt
文件中:在将此文件作为
source config.txt
源时,最后分配给变量的值将被存储并将生效,在这种情况下,变量将始终在此文件源的活动shell会话中保持以下值:上述变量的第一个赋值将被覆盖。
要解决这个问题,您必须将数据库变量存储到不同的文件中,例如
config-1.txt
和config-2.txt
。此外,逻辑应该被编写为使得相应的配置文件应该在执行SQL文件之前获得源。
为了实现这一点,许多可能解决方案中的一种可能性是:
所有的sql文件和配置文件都可以存储在两个不同的bash数组中,并且根据数组索引,在执行SQL文件指令之前应该获取配置文件。
我已经发布了一个修改过的shell脚本:
目录结构如下所示:
我希望这能解决你的问题。
更新:根据您的评论:
感谢您的回应,但在真实的情况下,我不知道有多少数据库连接,我需要添加在配置文件,所以我想给予所有的数据库细节在一个配置文件,然后通过所有的子文件夹迭代执行SQL脚本。
正如你提到的,在真实的场景中,数据库连接的数量是未知的。记住上面的要求,你需要遵循一些基于bash行为的结构。
config.txt
应包含所有数据库连接,但使用不同的变量名,例如DB_USER_0=FIRST
、DB_PASSWORD_0=password_0
、DB_USER_1=SECOND
等1.包含SQL脚本
first.sql
、second.sql
等的文件夹应按数字升序排列,如您在原始问题中提到的Folder1/first.sql
、Folder2/second.sql
请记住您的新要求(您在最初的问题中没有提到)和限制,您可以参考以下修改后的shell脚本,并根据您的需求使用它来增强功能:
相应的
config.txt
文件应采用以下格式: