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

如何在GitLab CI的Docker-in-Docker环境中运行Bash脚本

GitLab CI执行bash脚本报错:语法错误与pushd未找到

问题背景

我有一个用于构建Docker镜像的bash脚本,想要配置GitLab CI,使其在推送tag时自动构建镜像。我的.gitlab-ci.yml配置如下:

stages:
  - build

variables:
  DOCKER_DRIVER: overlay2
  DOCKER_TLS_CERTDIR: ''
  FF_NETWORK_PER_BUILD: 1
  CI_DEBUG_SERVICES: "true"
  GIT_SUBMODULE_STRATEGY: recursive

build:
  image: docker:27.1.0
  stage: build
  services:
    - docker:27.1.0-dind
  before_script:
    - echo '>>>>>> DEBUG - install bash'
    - apk add bash
  script:
    - echo '>>>>>> DEBUG - build the images'
    - source dockerbuild.sh -t latest
  only:
    - tags

我知道dind默认用sh而非bash,所以提前安装了bash,但运行时还是遇到以下错误:

$ apk add bash
fetch https://dl-cdn.alpinelinux.org/alpine/v3.20/main/x86_64/APKINDEX.tar.gz
fetch https://dl-cdn.alpinelinux.org/alpine/v3.20/community/x86_64/APKINDEX.tar.gz
(1/2) Installing readline (8.2.10-r0)
(2/2) Installing bash (5.2.26-r0)
Executing bash-5.2.26-r0.post-install
Executing busybox-1.36.1-r29.trigger
OK: 44 MiB in 75 packages
$ echo '>>>>>> DEBUG - build the images'
>>>>>> DEBUG - build the images
$ source dockerbuild.sh -t latest
/bin/sh: dockerbuild.sh: line 6: syntax error: bad substitution
/bin/sh: dockerbuild.sh: line 51: pushd: not found

报错对应的脚本行:

# Line 6
GIT_VERSION=$(git describe --tags --always --dirty)

# Line 51
pushd $LOCATION >/dev/null

解决方案

方案1:直接用bash执行脚本

将script中的source dockerbuild.sh -t latest替换为bash dockerbuild.sh -t latest,显式调用bash运行脚本,避免在sh环境中执行。

修改后的script部分:

script:
  - echo '>>>>>> DEBUG - build the images'
  - bash dockerbuild.sh -t latest

方案2:设置Job默认使用bash

在build job中添加SHELL变量,指定整个Job的脚本都用bash执行:

build:
  image: docker:27.1.0
  stage: build
  services:
    - docker:27.1.0-dind
  variables:
    SHELL: /bin/bash  # 添加此行
  before_script:
    - echo '>>>>>> DEBUG - install bash'
    - apk add bash
  script:
    - echo '>>>>>> DEBUG - build the images'
    - source dockerbuild.sh -t latest
  only:
    - tags

这样设置后,source命令会在bash环境中加载脚本,bash特有的语法(如pushd)就能正常工作。

原因说明

虽然你安装了bash,但GitLab CI默认使用/bin/sh作为Job的执行shell。source命令会在当前sh环境中执行脚本,而sh不支持bash的部分特性,因此触发报错。通过显式调用bash或修改Job默认shell,就能让脚本在正确的环境中运行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 16:58:18