如何将本地SQL文件带参数传到远程服务器执行?
解决本地SQL文件通过SSH在远程执行并传递参数的问题
你当前的核心需求是让本地SQL文件在远程服务器执行,同时传递参数,但修改后的脚本写法存在错误。问题根源在于混淆了sqlplus的@指令(读取远程文件)和本地文件重定向的用法,导致sqlplus无法正确读取本地文件内容。
修正后的可用脚本
function Runsshlocal { HOSTS=$1 SID=$2 file_in=$3 shift 3 SQL_PARAMS=$@ # 将本地SQL文件内容追加exit命令后,通过管道传给远程sqlplus output=$( cat "${file_in}" <(echo "exit") | ssh -q ${HOSTS} "ORAENV_ASK=NO;ORACLE_SID=${SID}; . oraenv -s; sqlplus -s \"/ as sysdba \" ${SQL_PARAMS}" ) echo "$output" } # 调用示例(注意变量加引号避免特殊字符问题) TEST=$(Runsshlocal "${TARGET_SERVER}" "${TARGET_SID}" "/localserver/xxxxx.sql" "${PARAM1}" "${PARAM2}") echo "$TEST"
关键修改说明
- 本地文件传递逻辑:用
cat "${file_in}" <(echo "exit")把本地SQL文件内容和exit命令拼接,通过管道传给远程SSH进程。这样sqlplus会从标准输入读取SQL语句,完全不需要依赖远程服务器上的文件。 - 参数传递方式:
${SQL_PARAMS}直接附加在远程的sqlplus命令后,SQL文件中可以用&1、&2这类占位符引用参数(比如SELECT * FROM table WHERE id = &1;)。 - 引号规范:给文件路径、变量引用加上双引号,避免路径含空格或变量值有特殊字符时出现解析错误。
- 自动退出处理:把
exit命令整合到输入流中,确保sqlplus执行完SQL后自动退出,不会因等待输入而卡住。
原修改失效的原因
你之前写的< @${file_in} ${SQL_PARAMS}是错误用法:@是sqlplus用来加载远程服务器本地文件的指令,而<是本地shell的重定向操作,两者不能混用。正确的思路是把本地文件内容直接通过管道发送到远程sqlplus的标准输入,让sqlplus读取执行。
内容的提问来源于stack exchange,提问作者Shaz
相关产品推荐
相关产品推荐

