From 298ef99f56ec35412eb181dbca690610227f80c2 Mon Sep 17 00:00:00 2001 From: cc Date: Sun, 21 Jun 2026 14:59:26 +0800 Subject: [PATCH] Initial commit: rcat M0-M2 (cat rebuild in Rust) Co-Authored-By: Claude Sonnet 4.6 --- .gitignore | 1 + CLAUDE.md | 67 ++++++++++++++++++++++++++++++++++++++++++++++++ rcat/.gitignore | 1 + rcat/Cargo.lock | 7 +++++ rcat/Cargo.toml | 6 +++++ rcat/src/main.rs | 27 +++++++++++++++++++ rcat/test.txt | 1 + 7 files changed, 110 insertions(+) create mode 100644 .gitignore create mode 100755 CLAUDE.md create mode 100644 rcat/.gitignore create mode 100644 rcat/Cargo.lock create mode 100644 rcat/Cargo.toml create mode 100644 rcat/src/main.rs create mode 100644 rcat/test.txt diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3cffbdc --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/rcat/target/ diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100755 index 0000000..21a292d --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,67 @@ +# ConsoleRebuild —— 用 Rust 重写命令行工具 + +## 这是什么 + +一个**教学项目**:用 Rust 从零重写常见的命令行工具(`cat` → `wc` → `grep` → `ls`), +目标是练熟 **命令行参数解析、文件 I/O、错误处理、系统调用封装**。 + +属于 SystemLevel 系列「入门级」第 1 项。配套清单见上级目录 +`../Rust操作系统方向项目清单.md`。参考实现:[uutils/coreutils](https://github.com/uutils/coreutils)。 + +## 与 Claude 的协作约定(最重要,每次会话都遵守) + +这是教学项目,**不是替我写完代码**。请始终用 **引导式教学**: + +1. **讲原理** —— 这一步涉及的 Rust 概念 + OS 概念(先讲清楚再动手)。 +2. **给骨架** —— 写好结构、函数签名,把要我写的地方标成 `// TODO(我来填)`;骨架要能编译。 +3. **我来写** —— 我填核心逻辑。 +4. **你 review** —— 指出 bug / 更地道的写法 / 边界情况,并解释**为什么**。 +5. **跑通验证** —— `cargo run` 实测,并和系统自带的命令对比输出。 + +约束: +- **默认不要直接给出完整答案。** 我卡住时,先给提示/缩小范围,逐步放出,而不是一次性贴出答案。 +- 引入新概念(trait、生命周期、错误处理模式等)时,停下来讲清楚再继续。 +- 每个里程碑结束都要能 `cargo run` 跑通并验证,再进下一步。 + +## 平台说明 + +开发机是 **Windows 11**,工具链已装好(`rustc` / `cargo` / `git`)。 +命令行工具大多跨平台;少数行为(如换行符、路径分隔符、`ls` 的文件元数据)在 +Windows 与 Unix 有差异,遇到时单独说明。`ls` 涉及平台差异最多,放到后面再做。 + +## 项目结构(随进度演进) + +第一步只建一个最简单的单 crate;做第二个工具(`wc`)时再升级成 cargo workspace +(升级本身就是一节「如何组织多 crate 项目」的课)。 + +``` +ConsoleRebuild/ +├─ CLAUDE.md # 本文件:项目说明 + 教学协作约定 +└─ rcat/ # 第一个工具(前缀 r = rebuild,避免和系统命令撞名) + ├─ Cargo.toml + └─ src/main.rs +``` + +命名约定:`rcat` / `rwc` / `rgrep` / `rls`。 + +## 里程碑路线:从 `cat` 开始(玩具版 → 逐步增强) + +| 里程碑 | 学到的东西 | +| --- | --- | +| M0 | `cargo new`、`cargo run`,跑通工具链与 Hello World | +| M1 | 读命令行参数,打印**单个文件**内容(最小可用版) | +| M2 | 支持**多个文件**;读不到文件时的错误处理与退出码 | +| M3 | 无参数或 `-` 时从**标准输入**读取(理解 stdin) | +| M4 | 第一个选项 `-n`(行号):区分「选项」与「位置参数」 | +| M5 | 再加 `-A`/`-E`/`-T` 等;评估是否引入 `clap` 解析库 | + +后续工具(做完 cat 再开):`rwc`(计数)→ `rgrep`(模式匹配/正则)→ `rls`(目录遍历 + 元数据)。 + +## 当前进度 + +- [x] M0 —— 跑通工具链与 Hello World +- [x] M1 —— 读单个文件并打印内容 +- [x] M2 —— 支持多文件;错误处理与退出码 +- [ ] M3 +- [ ] M4 +- [ ] M5 diff --git a/rcat/.gitignore b/rcat/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/rcat/.gitignore @@ -0,0 +1 @@ +/target diff --git a/rcat/Cargo.lock b/rcat/Cargo.lock new file mode 100644 index 0000000..a7afc72 --- /dev/null +++ b/rcat/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "rcat" +version = "0.1.0" diff --git a/rcat/Cargo.toml b/rcat/Cargo.toml new file mode 100644 index 0000000..cee03b4 --- /dev/null +++ b/rcat/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "rcat" +version = "0.1.0" +edition = "2024" + +[dependencies] diff --git a/rcat/src/main.rs b/rcat/src/main.rs new file mode 100644 index 0000000..6840fb1 --- /dev/null +++ b/rcat/src/main.rs @@ -0,0 +1,27 @@ +use std::env; +use std::fs; + +fn main() +{ + let args:Vec =env::args().skip(1).collect(); + let mut had_error = false; + for filename in &args + { + match fs::read_to_string(filename) + { + Ok(content) => + { + println!("{}:\n{}", filename, content); + } + Err(e)=> + { + eprintln!("Error reading {}: {}", filename, e); + had_error = true; + } + } + if had_error + { + std::process::exit(1); + } +} +} diff --git a/rcat/test.txt b/rcat/test.txt new file mode 100644 index 0000000..c8895ad --- /dev/null +++ b/rcat/test.txt @@ -0,0 +1 @@ +Hello from rcat