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

使用自定义Docker镜像时GitLab CI/CD流水线报'do'语法错误

问题描述

使用包含Terraform、Terragrunt和AWS CLI的自定义Docker镜像运行GitLab CI/CD流水线时,第一阶段失败,报错如下:

Executing "step_script" stage of the job script
00:01
Using docker image sha256:e1589e57615ab7e4c9ffe424070fef53c53c17a040de2c5ee858fff319753f2a for registry.gitlab.com/image-path:terragrunt-latest with digest registry.gitlab.com/image-path@sha256:0d5c661e1dce3f543af65966daa947a9e3878316b95464cbb3c3187d19e01d40 ...
sh: 7: Syntax error: "do" unexpected
Cleaning up project directory and file based variables
00:01
ERROR: Job failed: exit code 2

已完成操作

  • 基于Ubuntu 22.04构建自定义镜像,安装Terraform、Terragrunt、AWS CLI等工具后推送至GitLab容器仓库:
    docker build -t registry.gitlab.com/my-project/my-repo:latest .
    docker push registry.gitlab.com/my-project/my-repo:latest
    
  • 在.gitlab-ci.yml中配置使用该自定义镜像。

额外信息

GitLab Runner版本为17.7.0~pre.103.g896916a8,执行器为docker+machine,基础镜像为Ubuntu 22.04。

问题

导致该语法错误的原因是什么?GitLab CI运行入口脚本是否存在问题?该如何进一步调试?


解答

错误原因分析

sh: 7: Syntax error: "do" unexpected这类报错核心是shell环境不兼容或脚本语法不符合规范,常见场景包括:

  1. 默认shell为Dash而非Bash:Ubuntu 22.04中sh默认指向轻量级shell Dash,它不支持部分Bash专属语法(比如无分隔符的多行循环写法、扩展变量等)。如果流水线脚本依赖Bash特性,用Dash执行就会触发语法错误。
  2. 脚本语法不规范:流水线脚本第7行的循环写法不符合POSIX Shell标准,比如for循环后未加;就直接换行写do,例如:
    # Dash不支持的错误写法
    for item in $(ls)
    do
      echo $item
    done
    # 兼容POSIX的正确写法
    for item in $(ls); do
      echo $item
    done
    
  3. Docker镜像未配置默认Bash:如果自定义镜像未通过SHELL指令指定默认shell为Bash,GitLab Runner会默认用sh执行脚本,触发兼容性问题。

GitLab CI入口脚本是否有问题?

大概率不是GitLab CI入口脚本的问题,而是你的流水线脚本或镜像shell配置的问题。GitLab CI的入口脚本兼容标准POSIX语法,仅当脚本依赖Bash特性但未指定shell时才会出错。

调试与解决步骤

  1. 定位报错脚本行:在GitLab流水线日志中展开step_script的完整内容,找到第7行的具体命令,确认是否存在语法问题。
  2. 本地镜像测试:拉取自定义镜像,本地模拟CI环境执行脚本,复现错误:
    docker run -it registry.gitlab.com/my-project/my-repo:latest sh
    # 粘贴流水线第7行及后续脚本,观察是否触发相同报错
    
  3. 显式指定Bash执行:在.gitlab-ci.yml的job中强制使用Bash:
    your_job_name:
      image: registry.gitlab.com/my-project/my-repo:latest
      variables:
        SHELL: "/bin/bash"
      script:
        - # 你的流水线脚本内容
    
    或者直接用Bash包裹单条脚本:
    script:
      - bash -c "your-script-with-bash-syntax"
    
  4. 修改Dockerfile配置默认shell:在Dockerfile中添加指令,确保镜像默认使用Bash:
    SHELL ["/bin/bash", "-c"]
    
  5. 修正脚本语法:如果是脚本本身的语法问题,将循环等语句调整为POSIX兼容格式,比如在for和do之间添加;分隔符。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 05:53:17