多服务器执行sqlplus脚本失败:Bash管道及命令缺失问题
多服务器异步执行SQL脚本的Bash脚本修复
问题1:本地SQL文件无法被远程sqlplus识别
你当前的命令是让远程服务器执行sqlplus时读取localfileToExecuteOnDistServ.sql,但这个文件仅存于本地,远程服务器找不到它。解决方法是通过管道将本地文件内容传递给远程的sqlplus,无需在远程服务器存储该文件:
修改commande函数中的ssh命令:
commande() { ssh user@$1 "sqlplus -s -l \"$dbconnect\"" < localfileToExecuteOnDistServ.sql }
问题2:sqlplus: command not found错误
这个错误是因为远程服务器的sqlplus不在当前SSH会话的PATH环境变量中,有两种解决方式:
- 直接使用
sqlplus的绝对路径(根据你的Oracle安装路径调整,示例路径为/u01/app/oracle/product/11.2.0/dbhome_1/bin/sqlplus) - 在ssh命令中先加载Oracle的环境变量脚本
示例(使用绝对路径):
commande() { ssh user@$1 "/u01/app/oracle/product/11.2.0/dbhome_1/bin/sqlplus -s -l \"$dbconnect\"" < localfileToExecuteOnDistServ.sql }
示例(加载环境变量):
commande() { ssh user@$1 "source /u01/app/oracle/.bash_profile && sqlplus -s -l \"$dbconnect\"" < localfileToExecuteOnDistServ.sql }
完整修正后的脚本
原脚本中declare -p result=()语法错误,且异步输出收集逻辑需要调整以避免乱序问题,以下是完整修复版:
# 定义服务器列表 declare -ra serveurs=("a" "b" ... "x" "y" "z") # 定义结果数组 declare -a result=() # 异步执行的任务函数 commande() { # 替换为你的sqlplus绝对路径或环境变量加载命令 echo "=== 服务器 $1 执行结果 ===" ssh user@$1 "/path/to/sqlplus -s -l \"$dbconnect\"" < localfileToExecuteOnDistServ.sql } # 启动所有异步任务并收集结果 while read -r output; do result+=("$output") done < <( for s in "${serveurs[@]}"; do commande "$s" & done wait # 等待所有后台任务完成 ) # 输出格式化后的结果 echo "=== 所有服务器执行汇总 ===" for line in "${result[@]}"; do echo "$line" done
额外提示
- 建议在结果前添加服务器标识(如脚本中的
echo "=== 服务器 $1 执行结果 ==="),方便区分各服务器的输出 - 确保
$dbconnect变量已正确定义(格式示例:dbconnect="username/password@dbinstance") - 异步执行虽能节省时间,但需注意避免给服务器或网络造成过大负载
内容的提问来源于stack exchange,提问作者Hiul_Dragonfel
相关产品推荐
相关产品推荐

