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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 01:27:28