仓库里没有 .gitattributes。deploy/bootstrap.sh 在 index 里是 LF,在 Windows 工作区里是 CRLF(2374 个 CR),而 go:embed 嵌的是工作区的字节,不是 index 的。
.gitattributes
deploy/bootstrap.sh
go:embed
于是在 Windows 上构建的 felis 二进制里,嵌进去的 bootstrap.sh 带 CRLF。TUI 安装路径把这段脚本直接 pipe 进目标 Linux 主机的 bash -s —— shebang 后面挂着 \r、变量赋值末尾带 \r、[ "$x" = yes ] 的比较对象是 yes\r。
felis
bash -s
\r
[ "$x" = yes ]
yes\r
CI 用 Linux runner 构建,所以发布的二进制不受影响。受影响的是任何在 Windows 上 go build 出来的 felis,包括开发过程中用来装测试环境的那一个。
go build
Identified by Claude Opus 5 (claude-opus-5) while auditing the embed path on 2026-07-28.
bootstrap_asset.go:10-11:
bootstrap_asset.go:10-11
//go:embed deploy/bootstrap.sh var bootstrapScript string
当前状态:
$ git ls-files --eol deploy/bootstrap.sh i/lf w/crlf attr/ deploy/bootstrap.sh $ ls .gitattributes ls: cannot access '.gitattributes': No such file or directory
attr/ 那一栏是空的 —— 没有任何属性规则在管这个文件,core.autocrlf=true 说了算。
attr/
core.autocrlf=true
加 .gitattributes 之后 git ls-files --eol deploy/bootstrap.sh 报 w/lf,且 attr/text eol=lf。
git ls-files --eol deploy/bootstrap.sh
w/lf
attr/text eol=lf
规则应该覆盖所有会被嵌进二进制或送到 Linux 上执行的文本:*.sh、Dockerfile、entrypoint。改完要 git add --renormalize . 一次,否则已有的工作区文件不会自动转。
*.sh
git add --renormalize .
71e1664。.gitattributes 加上 * text=auto eol=lf(*.bat 例外,gradle 的 Windows 启动器要 CRLF),并 renormalize 了整个索引。
* text=auto eol=lf
*.bat
现在 git ls-files --eol 里 i/crlf 的条目数是 0,deploy/bootstrap.sh 的 CR 字节数是 0 —— 这条要紧是因为 bootstrap_asset.go 是把它逐字 embed 进二进制再 bash -s 管进去的,带 CR 的 shebang 和 heredoc 终止符在 Linux 上会直接坏掉。
git ls-files --eol
i/crlf
bootstrap_asset.go
Verified by Claude Opus 5 (claude-opus-5) on 2026-07-28.
No dependencies set.
The note is not visible to the blocked user.
问题
仓库里没有
.gitattributes。deploy/bootstrap.sh在 index 里是 LF,在 Windows 工作区里是 CRLF(2374 个 CR),而go:embed嵌的是工作区的字节,不是 index 的。于是在 Windows 上构建的
felis二进制里,嵌进去的 bootstrap.sh 带 CRLF。TUI 安装路径把这段脚本直接 pipe 进目标 Linux 主机的bash -s—— shebang 后面挂着\r、变量赋值末尾带\r、[ "$x" = yes ]的比较对象是yes\r。CI 用 Linux runner 构建,所以发布的二进制不受影响。受影响的是任何在 Windows 上
go build出来的 felis,包括开发过程中用来装测试环境的那一个。证据
Identified by Claude Opus 5 (claude-opus-5) while auditing the embed path on 2026-07-28.
bootstrap_asset.go:10-11:当前状态:
attr/那一栏是空的 —— 没有任何属性规则在管这个文件,core.autocrlf=true说了算。验收
加
.gitattributes之后git ls-files --eol deploy/bootstrap.sh报w/lf,且attr/text eol=lf。备注
规则应该覆盖所有会被嵌进二进制或送到 Linux 上执行的文本:
*.sh、Dockerfile、entrypoint。改完要git add --renormalize .一次,否则已有的工作区文件不会自动转。71e1664。
.gitattributes加上* text=auto eol=lf(*.bat例外,gradle 的 Windows 启动器要 CRLF),并 renormalize 了整个索引。现在
git ls-files --eol里i/crlf的条目数是 0,deploy/bootstrap.sh的 CR 字节数是 0 —— 这条要紧是因为bootstrap_asset.go是把它逐字 embed 进二进制再bash -s管进去的,带 CR 的 shebang 和 heredoc 终止符在 Linux 上会直接坏掉。Verified by Claude Opus 5 (claude-opus-5) on 2026-07-28.