# Windows 开发 / Ubuntu 部署 — 字符与换行审计 | 项 | 内容 | |----|------| | 日期 | 2026-06-02 | | 范围 | 换行符 (LF/CRLF)、UTF-8、路径分隔符、部署脚本、远程文件 EOL | | 生产目标 | Ubuntu(Supervisor + bash),开发机常见为 Windows | ## 结论摘要 | 类别 | 状态 | 说明 | |------|------|------| | 远程 Linux 路径 | ✅ 已治理 | `server/utils/posix_paths.py` + 2026-06-01 全量审计 | | 远程文件 UTF-8 | ✅ | 读写 `utf-8` / `errors=replace`,SFTP 二进制 | | 远程文件 EOL | ✅ 有意支持 | API 返回 `eol: LF\|CRLF`,前端按原 EOL 写回 | | `.gitattributes` | ✅ 已配置 | `*.sh` / `*.py` → `eol=lf` | | 工作区 CRLF 泄漏 | ⚠️ 发现 14 个 `.sh` | 见下表;已在本次审计中转为 LF | | 部署路径 | ⚠️ 流程风险 | Windows 应用 **WSL/Git Bash** 跑 `deploy/*.sh`;勿用 PowerShell 直接 `tar` 打包(曾出现空包) | | 门控 | ✅ 补强 | `deploy/check_shell_eol.sh`,接入 `pre_deploy_check.sh` | --- ## 1. 换行符 (CRLF vs LF) ### 风险 Ubuntu 上执行带 CR 的 shell 脚本会出现 `\r: command not found` 或 `bad interpreter`。历史记录见 `docs/changelog/2026-05-27-agent-install-fix-and-deploy.md`。 ### 仓库策略(`.gitattributes`) ``` *.sh text eol=lf *.py text eol=lf *.bat / *.cmd text eol=crlf ``` ### 本次扫描(Windows 工作区,2026-06-02) 以下文件检出 **CRLF**(已在本轮修复为 LF): | 文件 | |------| | `deploy/db_backup.sh` | | `deploy/health_monitor.sh` | | `deploy/install.sh` | | `deploy/pre_deploy_check.sh` | | `deploy/run_test_api_on_server.sh` | | `deploy/uninstall.sh` | | `deploy/upgrade.sh` | | `scripts/run_full_acceptance.sh` | | `scripts/wsl_*.sh`(5 个) | | `web/agent/agent.sh` | **已为 LF(无需改)**:`deploy/deploy-frontend.sh`、`web/agent/install.sh`、`scripts/run_full_e2e.sh` 等。 ### 开发机建议 ```bash git config core.autocrlf false git add --renormalize '*.sh' '*.py' ``` 推送前在 WSL 或 CI 上执行:`bash deploy/check_shell_eol.sh` --- ## 2. 字符编码 (UTF-8) | 位置 | 处理 | |------|------| | API 读远程文件 | `cat` → Python `str`,响应当 UTF-8 JSON | | API 写远程文件 | `payload.content.encode("utf-8")` | | 本机读推送源 | `open(..., encoding="utf-8", errors="replace")` | | 安装向导写 `.env` / `config.json` | `Path.write_text`,`\n` 连接(Linux 安装目标为 LF) | | 前端 | Vite/浏览器默认 UTF-8;Monaco 按 UTF-8 编辑 | **注意**:Windows 记事本「UTF-8 BOM」写入的 `.env` 可能导致首行 key 带 BOM;安装向导应在 Linux 生成配置,勿在 Windows 记事本手改后上传。 --- ## 3. 路径(反斜杠 vs `/`) | 层 | 状态 | |----|------| | 后端远程路径 | ✅ `posix_paths` / `normalize_remote_abs_path`,拒绝 `\` | | 前端 `remotePath.ts` | ✅ `normalizeRemotePath` + `coercePathString`(防 Ref/非字符串) | | 后端 `os.path.join` 用于远程 | ✅ 已清除(仅本机 FS 与文档注释保留) | 详见:`docs/audit/2026-06-01-posix-path-full-audit.md` --- ## 4. 远程文件 EOL(业务语义,非缺陷) - `POST /sync/read-file`:`eol = "CRLF" if "\r\n" in content else "LF"` - 前端 `FileEditorWorkbench`:内部比较用 LF;保存时 `serializeContent(..., tab.eol)` 恢复原 EOL - 测试:`tests/test_editor_write_conflict.py` 覆盖 CRLF 写回 在 Ubuntu 上编辑 Windows 生成的 `\r\n` 文件是**预期行为**,不是编码错误。 --- ## 5. 部署流程(Windows → Ubuntu) | 操作 | 推荐 | 避免 | |------|------|------| | 后端部署 | `git push` + 服务器 `git pull` + `supervisorctl restart` | 在 Windows 上改服务器 `.sh` 用 CRLF 保存 | | 前端部署 | WSL/Git Bash:`bash deploy/deploy-frontend.sh` | PowerShell `tar` 路径/工作目录错误导致空包 | | 门控 | 服务器或 WSL:`bash deploy/pre_deploy_check.sh` | 跳过门控直接覆盖 `web/app` | | Agent 脚本 | 目标机 `bash install.sh`(仓库内须 LF) | `sh` 执行 CRLF 脚本 | --- ## 6. Closure(规则扫描) | H | 判定 | 依据 | |---|------|------| | H1 注入 | N/A | 本审计无代码逻辑变更(EOL 脚本除外) | | H2 路径 | PASS | posix_paths 已覆盖远程路径 | | H3 编码 | PASS | API/前端 UTF-8;EOL 显式建模 | | H4 CRLF 脚本 | FINDING→已修 | 14 个 `.sh` CRLF;已 LF 化 + 门控 | | H5 部署 | WARN | 文档化 Windows tar/PS 风险 | ## DoD - [x] 扫描仓库 `.sh` CRLF - [x] 核对 `.gitattributes`、posix 路径审计、read/write-file EOL - [x] 新增 `deploy/check_shell_eol.sh` 并接入 pre_deploy - [x] 修复检出 CRLF 的 shell 脚本 - [x] changelog 记录 - [ ] 可选:CI 增加 `check_shell_eol.sh`(Gitea Actions) ## 涉及文件(本轮) - `docs/audit/2026-06-02-windows-ubuntu-encoding-audit.md`(本文件) - `deploy/check_shell_eol.sh` - `deploy/pre_deploy_check.sh`(调用 EOL 检查) - 上述 14 个 `.sh`(CRLF→LF)