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

SSH Bash脚本if语句问题:Yum/Apt服务器更新脚本修正

修正你的SSH批量更新服务器脚本

我帮你梳理下脚本里的几个关键问题,然后给出修正后的版本,顺便解释每个改动的原因:

原脚本的核心问题

  1. 远程命令没正确传递:你写的ssh -l ${USERNAME} ${HOSTNAME}之后的代码全是在本地执行的,根本没传到远程服务器上,这是最致命的问题。
  2. if条件语法错误:[[ $find_os='yum' ]]里的比较运算符两边没有空格,Bash会把整个$find_os='yum'当成一个非空字符串,导致条件永远为真,根本起不到判断作用。
  3. 命令执行逻辑问题:变量里的&&在直接用双引号包裹执行时,远程环境可能不会正确解析,导致命令执行失败。
  4. 错误提示位置不对:找不到包管理器的提示是在本地输出的,你根本不知道是哪台服务器出了问题。

修正后的脚本

#!/bin/bash

USERNAME="root"
HOSTS="host1 host2 host3"

for HOSTNAME in ${HOSTS}; do
    echo "开始更新服务器 ${HOSTNAME}..."
    ssh -l ${USERNAME} ${HOSTNAME} '
        # 远程执行:检测包管理器
        find_os=$(command -v yum || command -v apt-get)
        
        # 如果都没找到,输出错误并退出
        if [[ -z $find_os ]]; then
            echo "错误:该服务器既没有yum也没有apt-get包管理器"
            exit 1
        fi

        # 根据检测结果执行对应更新命令
        if [[ $find_os == "/usr/bin/yum" ]]; then
            yum check-update && yum -y update
        else
            apt update && apt -y upgrade
        fi
    '
done

改动说明

  • 远程命令包裹:把所有要在远程执行的逻辑用单引号包裹,这样SSH会把整个字符串作为命令发送到目标服务器执行,确保所有判断和命令都在远程运行。
  • 修复条件判断:用[[ $find_os == "/usr/bin/yum" ]]做判断,command -v返回的是命令的完整路径,这样判断更准确,避免出现同名命令的干扰;同时给比较运算符两边加上了空格,符合Bash语法规范。
  • 错误处理优化:在远程逻辑里判断find_os是否为空,如果为空就输出错误并退出,让你清楚知道哪台服务器有问题。
  • 增加进度提示:在本地添加了echo "开始更新服务器 ${HOSTNAME}...",方便你跟踪批量更新的进度。

可选:保留变量的写法

如果你想把更新命令存在变量里复用,可以用双引号包裹远程命令(注意转义远程变量的$),再用eval执行变量里的命令链:

#!/bin/bash

USERNAME="root"
HOSTS="host1 host2 host3"
apt_run="apt update && apt -y upgrade"
yum_run="yum check-update && yum -y update"

for HOSTNAME in ${HOSTS}; do
    echo "开始更新服务器 ${HOSTNAME}..."
    ssh -l ${USERNAME} ${HOSTNAME} "
        find_os=\$(command -v yum || command -v apt-get)
        if [[ -z \$find_os ]]; then
            echo \"错误:该服务器既没有yum也没有apt-get包管理器\"
            exit 1
        fi

        if [[ \$find_os == \"/usr/bin/yum\" ]]; then
            eval \"${yum_run}\"
        else
            eval \"${apt_run}\"
        fi
    "
done

这里用双引号让本地的yum_run和apt_run变量被正确替换,同时把远程的$find_os转义成\$,避免本地Shell提前解析这个变量。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 11:54:12