GitLab CI/CD执行release_bin脚本提示‘未找到’问题求助
问题分析与解决
核心原因
出现./release_bin: not found错误的本质不是脚本文件不存在,而是脚本指定的解释器在release阶段的镜像中缺失:
- build阶段使用的
golang:latest镜像自带完整bash环境,因此build_all可正常执行; - release阶段的
registry.gitlab.com/gitlab-org/cli:latest镜像基于Alpine Linux,默认仅提供/bin/sh(ash),没有/bin/bash,但release_bin的shebang是#!/bin/bash,系统找不到对应解释器,从而抛出“文件未找到”的错误。
此外,脚本中的for f in "./bin/*"存在逻辑问题:带引号会让shell将./bin/*当作单个文件名,而非通配匹配bin目录下的所有文件,需要修正。
解决方案
方案1:修改脚本适配/bin/sh
将release_bin的shebang改为#!/bin/sh,同时修正通配符的引号问题:
#!/bin/sh BINFILES="" # 移除引号,让shell解析通配符 for f in ./bin/* do BINFILES="$BINFILES $f" done echo $BINFILES glab auth login --hostname "$CI_SERVER_HOST" --token "$GLAB_TOKEN" glab release create "$CI_COMMIT_TAG" --name "Release $CI_COMMIT_TAG" \ -N "$CI_COMMIT_TAG_MESSAGE" $BINFILES
方案2:在release阶段安装bash
若不想修改脚本,可在release阶段的任务中先安装bash(适配Alpine镜像的包管理):
release: stage: release image: registry.gitlab.com/gitlab-org/cli:latest rules: - if: $CI_COMMIT_TAG script: - ls ./bin - ls . - apk add --no-cache bash # 新增安装bash的命令 - chmod +x release_bin - ./release_bin
额外优化:用数组存储文件路径(更健壮)
无论采用哪种方案,使用数组存储文件路径比字符串拼接更可靠,可避免文件名包含空格时出现异常:
#!/bin/sh # 用数组存储所有bin目录下的文件 BINFILES=(./bin/*) echo "${BINFILES[@]}" glab auth login --hostname "$CI_SERVER_HOST" --token "$GLAB_TOKEN" glab release create "$CI_COMMIT_TAG" --name "Release $CI_COMMIT_TAG" \ -N "$CI_COMMIT_TAG_MESSAGE" "${BINFILES[@]}"
内容的提问来源于stack exchange,提问作者eliotttak
相关产品推荐
相关产品推荐

