You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 06:06:02