症状
遇到“Cargo 权限被拒绝 — target 目录不可写”时靠猜测只会浪费时间。请按证据排查:先复现症状,再执行针对性诊断,定位根因后修复,并用明确检查验证结果。
可观察到的症状包括:
- cargo build 在 target/ 下报 “Permission denied (os error 13)”
- 曾以 root 构建一次后开始报错
- 只读挂载的 CI 缓存导致构建失败
诊断
先在隔离环境中复现故障,再按顺序执行以下检查,逐步缩小范围。
步骤 1
ls -ld target target/debug && stat -c "%U %a" target/debug
用户目录下存在 root 拥有的文件,即可解释写入失败。
步骤 2
CARGO_TARGET_DIR=/tmp/cargo-target cargo build
构建到可写的临时目录成功,即把问题定位到原 target。
常见诱因(按出现频率排序):
- 之前的构建以其他用户(常为 root)运行,使 target/ 文件不可写
- target 目录位于只读挂载或权限错误的共享缓存上
- .cargo-lock 被已死进程持有,成为残留锁
根因
Cargo 会在 target/ 下写入指纹、rlib 与锁。若这些文件属于其他用户,或位于只读挂载上,任何写入都返回 os error 13,编译无法进行。
修复
修正所有权(chown -R 到当前用户),避免以 root 构建,为 CI 提供可写的 CARGO_TARGET_DIR,并用 cargo clean 或删除 target/.cargo-lock 来清除残留锁。
注意:对容器内 target 做 chown -R 可能破坏其他挂载;应将改动限定在项目目录内。
# inspect and fix ownership
ls -ld target
sudo chown -R "$USER":"$USER" target
# or build into a clean, writable directory
CARGO_TARGET_DIR=/tmp/cargo-target cargo build --release
# clear a stale lock if a dead process held it
rm -f target/.cargo-lock
验证
以普通用户重跑 cargo build 并确认完成;验证 target 文件属于该用户。
修复后补充一条回归测试,复现原始症状,防止问题再次出现。
这类故障通常是环境问题而非纯逻辑错误,因此在缺陷记录中应写明完整命令、环境变量与工作目录。请用最小的脚本复现,待最小用例清楚后再扩大范围。为这类故障准备一份简短的排查清单,能显著减少下次排障时间。