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

Bash跨站点应用故障转移脚本:远程执行结果获取及语法问题

跨站点Pacemaker应用故障转移脚本问题

我正在编写Bash脚本实现跨站点应用故障转移,应用由Pacemaker管控。计划编写函数接收变量,实现应用在一个站点停止、另一个站点启动,但通过SSH连接远程机器后,无法获取PCS应用状态的grep/awk命令结果。

遇到的问题:

  • 本地用户有管理员设置的横幅,将SSH命令输出重定向到/dev/null 2>&1,-q参数无效,这是否会阻止结果返回?
  • 使用awk '{print \\\$4}'时,出现"backslash not last character on line"错误;
  • 尝试用result=$(sudo pcs status | grep nds_$resource)规避,却出现sudo密码错误;
  • 已尝试>/dev/tty和>$(tty);
  • 移除SSH的输出抑制(删除/dev/null 2>&1),函数调用时将输出存入变量,同时从sudo pcs status中移除awk,执行以下代码正常:
    result=$(pcs_call "$site1" "1" "2" "disable" "pmr")
    echo $result | grep systemd 
    
    但添加| awk '{print \\$4}'后得到的是横幅中的第四个单词。

测试用精简函数代码:

site1=lon
site2=ire


function pcs_call()
{
 site=$1
 serverA=$2
 serverB=$3
 activity=$4
 resource=$5

ssh -tt ${site}servername0${serverA}  <<SSH > /dev/null 2>&1
         sudo pcs resource ${activity} proc_${resource}
         sleep 10
         sudo pcs status  | grep proc_$resource | awk '{print \\$4}' | tee $output
         exit
SSH
echo $output
}

echo ====================================================================================
echo Shutting Down PMR in $site1
pcs_call "$site1" "1" "2" "disable" "pmr"

问题解决与脚本修正

1. SSH输出重定向导致结果丢失

把SSH的标准输出和错误全重定向到/dev/null会直接丢弃远程命令的所有输出,包括pcs status的结果,自然拿不到数据。要保留结果,不能全丢输出,而是要过滤横幅:

  • 用sed过滤横幅(假设横幅以空行结束):
    ssh ${site}servername0${serverA} "sudo pcs status" | sed '1,/^$/d'
    
  • 非必要情况下去掉-tt参数(强制伪终端会导致输出混乱),或用-T禁用伪终端避免横幅干扰。

2. awk变量转义错误

在Here Document(<<SSH)中,本地Shell会解析变量和转义字符:

  • 如果不需要在远程命令中使用本地变量,用<<'SSH'(单引号包裹分界符)禁用本地解析,远程awk的$4无需转义:
    ssh ${site}servername0${serverA} <<'SSH'
    sudo pcs status | grep proc_resource | awk '{print $4}'
    SSH
    
  • 如果需要使用本地变量(比如$resource),不能用单引号包裹分界符,此时awk的$4只需转义一次(\$4)即可,不需要三次转义。

3. sudo密码问题

远程执行sudo需要交互式输入密码,脚本中无处理导致错误,解决方式二选一:

  • 推荐:给远程用户配置免密sudo权限,编辑远程机器的/etc/sudoers(用visudo避免语法错误),添加规则:
    username ALL=(ALL) NOPASSWD: /usr/sbin/pcs
    
  • 非生产环境可临时用sshpass传递密码(不安全):
    sshpass -p 'yourpassword' ssh ${site}servername0${serverA} "sudo pcs ..."
    

4. 横幅混入输出导致awk取错内容

移除SSH输出抑制后,横幅会混入结果,可通过以下方式过滤:

  • 远程端直接跳过横幅行(假设横幅共3行):
    ssh ${site}servername0${serverA} "sudo pcs status | tail -n +4 | grep proc_$resource | awk '{print \$4}'"
    
  • 本地端过滤(只保留含目标资源的行):
    raw_result=$(ssh ${site}servername0${serverA} "sudo pcs status")
    clean_result=$(echo "$raw_result" | grep proc_$resource | awk '{print $4}')
    

修正后的完整函数

site1=lon
site2=ire

function pcs_call()
{
    local site=$1
    local serverA=$2
    local activity=$3
    local resource=$4

    # 使用本地变量时,Here Document不包裹单引号,awk的$4转义一次
    local output=$(ssh ${site}servername0${serverA} <<SSH
        sudo pcs resource ${activity} proc_${resource}
        sleep 10
        # 假设横幅前2行,根据实际情况调整行数
        sudo pcs status | tail -n +3 | grep proc_${resource} | awk '{print \$4}'
SSH
    )

    echo "$output"
}

echo "===================================================================="
echo "Shutting Down PMR in $site1"
pcs_call "$site1" "1" "disable" "pmr"

内容的提问来源于stack exchange,提问作者Red_badger

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 01:31:19