ksh嵌套远程函数调用报syntax error at line 5: `;;' unexpected错误求助
问题根因
- 两层SSH嵌套时函数定义的转义被破坏:你在本地执行
ssh HST1 "$(typeset -f); check_me"时,typeset -f输出的ksh格式函数定义,经过第一层SSH传输到HST1后,再在check_me函数里拼接第二层SSH命令ssh HST2 "$(typeset -f test_me); test_me"时,内部的双引号、函数定义里的特殊字符会被二次解析,导致语法结构被打乱,最终触发;; unexpected的语法错误。 - 目标主机默认shell不兼容:如果HST1/HST2的默认登录shell不是ksh,ksh格式的函数定义会被其他shell(比如低版本bash)解析错误。
修复方案
方案1:显式指定解释器+调整转义规则(适配你的原始逻辑)
修改后的完整脚本如下,通过显式指定ksh解释器、调整内外层引号规则避免转义冲突:
#!/bin/ksh set -x function test_me { set -x date } function check_me { set -x # 内层用单引号包裹函数定义,避免HST1执行时提前解析 ssh HST2 ksh -c ''"$(typeset -f test_me)"'; test_me' } # 外层显式调用ksh解析,避免HST1默认shell不兼容 ssh HST1 ksh -c "'$(typeset -f); check_me'"
方案2:逻辑打包序列化(适配多层跳转场景)
如果需要跳转更多节点,建议将远端执行逻辑整合成单个字符串传递,彻底避免逐层转义的问题:
#!/bin/ksh set -x # 把所有远端逻辑打包 remote_all=$(cat <<'EOF' function test_me { set -x date } function check_me { set -x ssh HST2 ksh -c "'$(typeset -f test_me); test_me'" } check_me EOF ) # 直接传给HST1的ksh解释器执行 ssh HST1 ksh -c "$remote_all"
适配你的RAC场景优化示例
针对你需要从RAC1A遍历RAC1B/C/D查数据库列表的需求,调整后的可直接复用脚本如下:
#!/bin/ksh set -x # 配置你的RAC节点列表 RAC_NODES=("RAC1B" "RAC1C" "RAC1D") # 单节点查数据库列表的逻辑,可自行修改适配你的环境 function get_instance_list { set -x ps -ef | grep ora_pmon | grep -v grep | awk '{print $NF}' | sed 's/^ora_pmon_//' } # 跳转单个RAC子节点执行查询 function query_node_db { typeset target_node=$1 ssh $target_node ksh -c "'$(typeset -f get_instance_list); get_instance_list'" } # 第一层跳转到RAC1A后执行批量遍历 ssh RAC1A ksh -c "' $(typeset -f get_instance_list query_node_db) RAC_NODES=(${RAC_NODES[*]}) for node in \${RAC_NODES[@]}; do echo \"===== 节点\$node 数据库列表 =====\" query_node_db \$node done '"
验证前提
确保SSH免密配置正常:
- SATH节点到RAC1A(HST1)的SSH免密登录
- RAC1A到所有RAC子节点的SSH免密登录
内容的提问来源于stack exchange,提问作者rman oracle
相关产品推荐
相关产品推荐

