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

如何在Shell脚本if-else块中SSH连接VM?解决语法报错问题

Jenkins Shell脚本if-else块报错及SSH连接解决方案

报错原因排查

出现Syntax error: end of file unexpected (expecting "fi")通常和以下几个问题有关:

  • 换行符不兼容:脚本用Windows编辑器编写,换行符是\r\n,Linux环境下会把\r识别为字符,导致fi语句被截断,Shell无法识别闭合标记。
  • SSH命令的语法冲突:if块内的SSH命令如果使用未转义的引号、或者嵌套了与本地Shell语法冲突的符号(比如{}、$()),会干扰本地Shell对if-else结构的解析,提前终止脚本。
  • 语法拼写错误:fi拼写错误(比如写成FI)、if/else块未正确对齐、或者存在多余的特殊字符(比如不可见的空格)。

正确实现示例

以下是符合要求的完整Shell脚本,包含容器状态判断、镜像推送、SSH远程执行脚本的逻辑:

#!/bin/bash

# 定义容器名称和镜像信息
CONTAINER_NAME="app-container"
IMAGE_TAG="your-registry/app:latest"
REMOTE_VM="deploy-user@192.168.1.100"

# 检查容器是否运行
if docker inspect --format '{{.State.Running}}' "$CONTAINER_NAME" | grep -q "true"; then
    # 容器运行中:推送镜像到仓库
    echo "推送镜像 $IMAGE_TAG..."
    docker push "$IMAGE_TAG"

    # SSH连接远程VM执行refresh脚本
    ssh "$REMOTE_VM" << 'REMOTE_EOF'
        # 远程服务器上的操作
        cd /opt/app-deploy
        chmod +x refresh.sh
        ./refresh.sh
        echo "远程刷新完成"
REMOTE_EOF
else
    # 容器未运行:导出日志并清理资源
    echo "容器未运行,导出错误日志..."
    docker logs "$CONTAINER_NAME" > /var/log/jenkins/container-fail.log 2>&1
    docker stop "$CONTAINER_NAME" || true
    docker rm "$CONTAINER_NAME" || true
fi

关键注意事项

  1. 指定Shell解释器:脚本开头必须加#!/bin/bash,避免Jenkins使用默认的sh(语法限制更多,容易触发兼容性问题)。
  2. SSH here-doc写法:使用<< 'REMOTE_EOF'(单引号包裹分界符),这样远程命令中的变量、特殊符号不会被本地Shell解析,避免语法冲突;如果需要传递本地变量到远程,去掉单引号即可,但要注意转义特殊字符。
  3. 容器状态检查:用docker inspect配合grep -q做静默判断,避免输出内容干扰脚本逻辑。
  4. 容错处理:清理资源时加|| true,防止容器已经停止/删除时命令失败,导致脚本终止。

报错修复步骤

  1. 转换换行符:如果脚本是Windows环境编写的,用dos2unix转换为Linux格式:
    dos2unix your-jenkins-script.sh
    
  2. 验证语法:在本地执行bash -n your-jenkins-script.sh,检查脚本语法是否有错误,提前定位问题。
  3. 检查引号嵌套:如果远程命令需要使用引号,用转义符处理,比如远程命令中的单引号写成'\'',或者改用双引号包裹远程命令块(注意变量解析的差异)。
  4. 替换分界符:如果脚本中存在多个here-doc,避免使用相同的分界符(比如都用EOF),改用不同的名称(比如REMOTE_EOF、LOCAL_EOF),防止提前结束代码块。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 21:43:27