GitHub Workflow无法执行shell脚本内的自定义do_hash函数
问题根因
问题出在生成generate-release.sh的步骤:YAML里为了格式对齐给shell代码加的前导空格,被echo原样写入了目标脚本文件。
普通shell heredoc语法要求结束标记EOF必须顶格书写,不能带任何前导空白字符。你生成的脚本里,EOF行前面带了大量缩进空格,shell无法识别这是heredoc的结束位置,会把EOF标记、后续的do_hash函数调用全当成heredoc的文本内容直接输出,根本不会执行后续逻辑。
另外用echo拼接多行shell脚本本身就容易出现引号转义、格式错乱问题,不推荐在Workflow里这么写。
你本地运行正常是因为本地手写脚本时EOF是顶格无缩进的,Workflow生成脚本时带入的额外缩进破坏了语法规则。
修复方案
二选一即可。
方案1:直接在Workflow步骤内执行逻辑,不生成独立脚本
最省事,完全不用处理写文件的转义、缩进问题:
- name: Generating Release shell: bash run: | set -e do_hash() { HASH_NAME=$1 HASH_CMD=$2 echo "${HASH_NAME}:" for f in $(find -type f); do f=$(echo "$f" | cut -c3-) # 移除./前缀 if [ "$f" = "Release" ]; then continue fi echo " $(${HASH_CMD} "$f" | cut -d" " -f1) $(wc -c < "$f")" done } mkdir -p example/apt-repo/dists/stable cat << EOF > example/apt-repo/dists/stable/Release Origin: Example Repository Label: Example Suite: stable Codename: stable Version: 1.0 Architectures: amd64 arm64 arm7 Components: main Description: An example software repository Date: $(date -Ru) EOF do_hash "MD5Sum" "md5sum" >> example/apt-repo/dists/stable/Release do_hash "SHA1" "sha1sum" >> example/apt-repo/dists/stable/Release do_hash "SHA256" "sha256sum" >> example/apt-repo/dists/stable/Release
注意这里heredoc的结束标记EOF要和run块内的代码对齐,不要加额外前导空格。
方案2:保留独立脚本逻辑,修正文件生成写法
如果一定要生成独立的sh文件,用外层heredoc写文件替代echo拼接,避免格式错乱:
- name: Generating Release run: | cat > example/generate-release.sh << 'SCRIPT_EOF' #!/bin/sh set -e do_hash() { HASH_NAME=$1 HASH_CMD=$2 echo "${HASH_NAME}:" for f in $(find -type f); do f=$(echo $f | cut -c3-) # remove ./ prefix if [ "$f" = "Release" ]; then continue fi echo " $(${HASH_CMD} ${f} | cut -d" " -f1) $(wc -c $f)" done } cat << EOF Origin: Example Repository Label: Example Suite: stable Codename: stable Version: 1.0 Architectures: amd64 arm64 arm7 Components: main Description: An example software repository Date: $(date -Ru) EOF do_hash "MD5Sum" "md5sum" do_hash "SHA1" "sha1sum" do_hash "SHA256" "sha256sum" SCRIPT_EOF - name: Run bash script shell: bash run: | chmod +x example/generate-release.sh mkdir -p example/apt-repo/dists/stable example/generate-release.sh > example/apt-repo/dists/stable/Release
这里几个关键点:
- 外层heredoc的结束标记
SCRIPT_EOF必须顶格(和run块内代码起始位置对齐,不能带前导空格) - 外层heredoc标记加单引号
'SCRIPT_EOF',可以避免写入时shell提前解析脚本内的变量、命令替换,保证写入内容和预期完全一致 - 提前创建目标输出目录,避免目录不存在导致重定向失败
内容的提问来源于stack exchange,提问作者Keval Bhogayata
相关产品推荐
相关产品推荐

