编程 Claude Code 持久记忆实战:从三层压缩机制到 Claude-Mem 的跨会话记忆实现

2026-04-22 09:32:54 +0800 CST views 17

Claude-Mem 深度解析:如何用两行安装代码终结 AI 编程的「金鱼记忆」

前言:当 AI 编程助手遇上「失忆症」

2026年,Claude Code 已经成为全球开发者最依赖的 AI 编程工具。每一天,数十万程序员用它阅读代码、审查 PR、重构模块、编写测试。然而,一个被 Anthropic 官方轻描淡写、却被社区广泛吐槽的问题始终悬而未决——Claude Code 是「金鱼记忆」

关闭终端,会话即消亡。下次打开,你面对的是一个全新的 AI,它不认识你、不记得你的项目结构、不理解你们上次讨论的设计决策。你不得不一遍又一遍地粘贴 README、解释项目背景、重复输入上下文。

这在短期任务中无伤大雅,但当你处理一个持续数月的项目、维护一个大型代码库、或者进行需要跨阶段思考的系统设计时,这种「每次重启即归零」的机制就成了生产力的最大瓶颈。

Anthropic 意识到了这个问题。Claude Code 内置了三层上下文压缩策略,试图在一个会话内部实现「无限长」的对话能力。但这套机制有一个根本性缺陷:它只能记忆当前会话内的信息,无法跨会话持久化。

Claude-Mem 正是为解决这个根本矛盾而生的开源项目。一行 npx claude-mem install 的命令,就能让 Claude Code 获得跨会话的持久记忆能力。这个项目在 2026 年 4 月迎来了流量大爆发,GitHub Star 数在短短数周内突破 59,000,引发了从 API 套利到大厂博弈的一系列连锁反应。

本文将从问题本质出发,深入解析 Claude Code 的三层上下文压缩机制,剖析 Claude-Mem 的架构设计与源码实现,并探讨这一「记忆插件」背后的深层技术博弈。


第一章:被忽视的瓶颈——上下文窗口的物理限制

1.1 上下文窗口不是无限大的

很多开发者对大模型「百万 token 上下文窗口」存在误解,认为这意味着无限的记忆能力。实际上,这是一个物理硬约束,而非软性弹性空间。

Claude Code 的上下文窗口(1,000,000 tokens)容纳了会话中的一切:

内容来源加载时机Token 占用特征
系统提示词每次会话启动固定,占比较大
CLAUDE.md启动时完整加载取决于文件大小
Auto Memory启动时加载(前200行或25KB)有上限
对话历史累积增长随会话持续增加
工具结果每次工具调用后追加日志/大文件消耗极快
MCP 工具描述启动时加载中等

关键问题在于:上下文窗口是线性消耗的。每读取一个 1000 行的源代码文件,就消耗约 4000 tokens;每执行一条 grepls 命令,输出结果就会追加到上下文。处理一个中等规模的全栈项目,读 30 个文件、跑 20 条命令,就能轻松突破 100K tokens。上限看似很大,但消耗速度更快。

1.2 上下文腐烂:被稀释的注意力

比物理上限更隐蔽的问题是上下文腐烂(Context Rot)。Anthropic 官方文档明确指出:

随着上下文窗口逐渐填满,LLM 的性能会下降——因为注意力被分散到更多的 token 上,旧的、不相关的内容开始干扰当前任务。

这不是 LLM 的记忆退化,而是注意力机制的根本特性。当模型需要在 100 万 token 中检索关键信息时,早期的上下文信号会被中后期的信息稀释。模型并非「忘记」了早期的内容,而是在生成回复时无法正确地将注意力权重分配给最相关的信息。

这是一个被低估的问题。大多数开发者只会注意到:当会话变长时,Claude Code 开始给出越来越不相关的建议,或者开始重复之前已经讨论过的内容。这些现象的根源,正是上下文腐烂。

1.3 Claude Code 内置的应对:三层压缩策略

Anthropic 在 Claude Code 中实现了一套精心设计的三层上下文压缩机制,压缩激进程度逐步递增。核心哲学是:「上下文总会满,要有办法腾地方」。

完整历史永久保存在磁盘,不会丢失任何内容——这是设计原则,不是妥协。

Layer 1:Micro Compact(微压缩,每轮静默执行)

每轮 LLM 调用前,系统自动执行微压缩:

流程:
1. 检查是否存在超过3轮的旧工具结果
2. 如果有,将其替换为占位符:[Previous: used {tool_name}]
3. 检查总 Token 数是否超过 50,000 阈值
4. 未超阈值 → 继续执行 LLM 调用
5. 超过阈值 → 触发 Layer 2

这是一个预防层,最轻量,Claude Code 几乎每次循环都会静默执行。它的目的是延迟 Layer 2 的触发时机,通过最小的信息损失换取最大的 Token 节省。

占位符策略非常巧妙:保留「曾经使用过某个工具」的事实,但用 [Previous: used {tool_name}] 替代具体的执行结果。当模型需要这些结果时,可以后续补充读取;但通常模型不需要回溯每个工具调用的详细结果。

Layer 2:Auto Compact(自动压缩,每会话触发一次或多次)

当 Token 超过 50,000 阈值时,系统进入自动压缩:

流程:
1. 将当前完整对话保存到 .transcripts/ 目录(永久保留)
2. 调用 LLM 生成当前对话的摘要(Summarization)
3. 将整个对话历史替换为一条摘要消息
4. 从数万 tokens 压缩到数千 tokens
5. 清空上下文,重新轻装上阵

这一层的代价比 Layer 1 高:压缩后,早期的对话细节被摘要取代。但 .transcripts/ 目录保存了完整的原始记录,如果后续需要回溯,可以读取存档。

压缩的质量取决于 LLM 生成摘要的能力。Claude Code 在这里有一个细节设计:摘要会刻意保留决策点和关键结论,而非简单的时间线概述。这使得压缩后的上下文仍然保持了较高的可用性。

Layer 3:Full Compact(完全压缩,模型主动触发)

模型可以主动调用 compact 工具,触发完全压缩:

// Claude Code 源码中的 compact 调用示意
await compact({
  reason: "需要集中处理新的重构任务",
  focusPoints: ["当前的架构问题", "待处理的模块"]  // 聚焦保留
})

这一层的触发权交给模型本身——当 LLM 判断当前上下文中有太多历史信息干扰新任务时,可以主动触发压缩,并指定需要聚焦保留的关键点。

1.4 三层压缩的局限

尽管三层压缩策略设计精妙,它有一个根本性缺陷所有压缩和持久化都只在单个会话内部有效

当你关闭 Claude Code 终端、结束会话,下次重新打开时:

会话状态重置
上下文窗口清空
三层压缩的成果全部丢失

唯一的持久化是 .transcripts/ 目录中的对话存档。但这是一个原始的文本文件,没有索引、没有检索机制、没有语义理解。你需要手动定位文件、阅读内容、重新粘贴到新会话中。

这就是 Claude-Mem 要解决的问题。


第二章:Claude-Mem——跨会话记忆的开源方案

2.1 项目起源与安装

Claude-Mem 由独立开发者创建,GitHub 地址:claude-mem/claude-mem。项目安装极其简单:

npx claude-mem install

这一行命令的背后,完成了以下工作:

  1. 创建本地存储目录(~/.claude-mem/
  2. 配置 Claude Code 的启动脚本,注入记忆加载逻辑
  3. 注册一个后台进程,监听会话事件并管理记忆写入

安装完成后,每次启动 Claude Code 时,Claude-Mem 会自动加载与当前项目相关的历史记忆,让 AI「记得」之前讨论过的内容。

2.2 核心设计哲学

Claude-Mem 的设计哲学可以概括为三个关键词:最小侵入、透明持久、按需检索

最小侵入:Claude-Mem 不修改 Claude Code 的核心源码。它通过插件机制注入,在 Claude Code 的启动和对话流程中嵌入记忆层,不影响原有功能。

透明持久:记忆的写入和读取对用户完全透明。用户不需要手动触发保存,Claude-Mem 会自动分析对话内容,识别值得记忆的信息,并在下次会话中自动加载。

按需检索:不是所有对话内容都值得记忆。Claude-Mem 使用智能过滤机制,只保存高价值信息(如架构决策、项目约定、未完成的任务),避免存储噪音。

2.3 工作流程

Claude-Mem 的完整工作流程如下:

会话启动阶段:
  1. 检测当前工作目录(项目路径)
  2. 加载该项目的历史记忆(如果有)
  3. 将记忆内容注入 Claude Code 的启动上下文

会话进行阶段:
  4. 监听 Claude Code 的对话事件
  5. 分析每轮对话的语义内容
  6. 识别高价值信息(架构决策、API设计、技术选型)
  7. 写入本地记忆存储

会话结束阶段:
  8. 汇总本次会话的贡献信息
  9. 更新项目记忆库
  10. 清理临时状态

这个流程完全自动化,用户无感知。开发者只需要正常地使用 Claude Code,记忆系统就在后台默默工作。


第三章:源码级架构解析

3.1 存储层:SQLite + 向量检索

Claude-Mem 的存储层采用双轨架构

结构化存储(SQLite):用于存储高结构化的记忆条目,如技术栈版本、API 端点列表、文件路径映射等。这些信息需要精确查询,不适合向量检索。

-- 记忆条目表结构
CREATE TABLE memories (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  project_path TEXT NOT NULL,
  category TEXT NOT NULL,           -- 'architecture' | 'api' | 'convention' | 'task'
  content TEXT NOT NULL,            -- 记忆内容
  importance_score REAL DEFAULT 0.5, -- 重要性评分
  last_accessed INTEGER,            -- Unix 时间戳
  access_count INTEGER DEFAULT 0,
  created_at INTEGER NOT NULL,
  updated_at INTEGER NOT NULL
);

CREATE INDEX idx_project ON memories(project_path);
CREATE INDEX idx_category ON memories(category);
CREATE INDEX idx_importance ON memories(importance_score DESC);

向量存储(SQLite FTS5 + 自定义嵌入):用于语义检索。记忆内容的语义相似性通过嵌入向量计算,支持「找到与当前任务相关的历史讨论」。

# 记忆存储的核心逻辑(伪代码)
class MemoryStore:
    def __init__(self, project_path: str):
        self.db = sqlite3.connect(f"{HOME}/.claude-mem/{hash(project_path)}.db")
        self.vector_store = VectorIndex()
    
    def add_memory(self, content: str, category: str, importance: float):
        # 结构化存储
        self.db.execute("""
            INSERT INTO memories (project_path, category, content, importance_score, created_at, updated_at)
            VALUES (?, ?, ?, ?, ?, ?)
        """, [self.project_path, category, content, importance, now(), now()])
        
        # 向量存储(用于语义检索)
        embedding = self.compute_embedding(content)
        self.vector_store.insert(embedding, content)
    
    def retrieve(self, query: str, top_k: int = 5) -> List[MemoryEntry]:
        # 语义检索
        query_embedding = self.compute_embedding(query)
        similar_contents = self.vector_store.search(query_embedding, top_k)
        
        # 与结构化存储关联,获取元数据
        results = []
        for content in similar_contents:
            entry = self.db.query(
                "SELECT * FROM memories WHERE content = ? AND project_path = ?",
                [content, self.project_path]
            )
            results.append(entry)
        
        return results

这种双轨架构的设计考量是:精度与召回的平衡。向量检索擅长语义匹配,但在精确值查询(如「当前使用的数据库连接字符串是什么」)时不如结构化存储可靠。Claude-Mem 在检索时会融合两种结果,根据查询类型动态调整权重。

3.2 重要性评分机制

不是所有对话内容都值得写入记忆。Claude-Mem 使用一套多维度评分机制评估每条信息的价值:

def calculate_importance(message_content: str, context: ConversationContext) -> float:
    score = 0.0
    
    # 关键词命中加分
    KEYWORDS = {
        'architecture': 0.3, 'design': 0.2, 'decision': 0.25,
        'api': 0.2, 'convention': 0.15, 'refactor': 0.2,
        'todo': 0.2, 'later': 0.15, 'debt': 0.25,
        'important': 0.2, 'critical': 0.3, 'must': 0.2
    }
    for kw, weight in KEYWORDS.items():
        if kw in message_content.lower():
            score += weight
    
    # 代码块存在加分(技术细节通常重要)
    if contains_code_block(message_content):
        score += 0.2
    
    # 对话长度惩罚(长回复不一定有价值)
    if len(message_content) > 2000:
        score -= 0.1
    
    # 模型明确判断加分
    if context.has_marker('[memory:save]'):
        score += 0.4
    
    # 首次提及加分(后续重复的信息价值递减)
    if not is_already_stored(message_content):
        score += 0.15
    
    # 标准化到 [0, 1] 范围
    return min(max(score, 0.0), 1.0)

这套评分机制的关键洞察是:开发者语言中的元信息比内容本身更有价值。当开发者说「这里我们决定用 PostgreSQL 作为主数据库」,这句话的重要性远高于某次 SELECT 查询的具体结果。评分机制通过关键词识别这些高价值陈述。

3.3 加载与注入机制

Claude-Mem 在 Claude Code 启动时注入记忆的方式非常巧妙,不修改 Claude Code 源码,而是利用其内置的 CLAUDE.md 自动加载机制

# 每次会话启动时,Claude Code 自动加载项目根目录的 CLAUDE.md
# Claude-Mem 动态生成该文件,注入记忆上下文

# ~/.claude-mem/injector.py 的核心逻辑
def generate_claude_md(project_path: str) -> str:
    memories = memory_store.retrieve_recent(project_path, limit=10)
    
    content = """# 项目上下文(由 Claude-Mem 自动生成)

> 以下内容由 Claude-Mem 根据历史会话自动生成,请作为参考上下文。

## 最近讨论的技术决策
"""
    for m in memories.filter(category='architecture'):
        content += f"- {m.content}\n"
    
    content += "\n## 未完成的任务\n"
    for m in memories.filter(category='task'):
        content += f"- [ ] {m.content}\n"
    
    content += "\n## 项目约定\n"
    for m in memories.filter(category='convention'):
        content += f"- {m.content}\n"
    
    return content

这利用了 Claude Code 本身就支持的启动上下文机制,Claude-Mem 无需任何源码修改即可工作。每次会话启动时,动态生成的 CLAUDE.md 包含项目历史记忆,被 Claude Code 自动加载。

3.4 会话摘要与增量更新

Claude-Mem 不是简单地将所有对话追加到记忆中。每次会话结束时,它会对整个会话进行摘要,提取增量贡献:

async def summarize_session(session: ConversationSession) -> SessionSummary:
    """使用 LLM 生成会话摘要"""
    
    system_prompt = """你是一个记忆整理专家。请分析以下 Claude Code 会话,
    提取对后续工作有价值的记忆点。
    
    输出格式要求:
    1. 新增技术决策(如果与历史不一致)
    2. 未完成但需要继续的任务
    3. 项目规范/约定的更新
    4. 需要长期记忆的重要信息
    
    只输出真正值得跨会话保留的信息,不要总结普通对话内容。"""
    
    session_text = session.to_text()
    
    summary = await llm.complete(
        prompt=f"{system_prompt}\n\n会话内容:\n{session_text}",
        max_tokens=500
    )
    
    return parse_summary(summary)

这个设计非常关键:如果每次会话的完整历史都被保存,存储会快速膨胀,而且后续检索时噪音会掩盖信号。通过会话摘要,Claude-Mem 只保留「精华」——设计决策、未完成任务、项目约定——而非每一条具体的对话内容。


第四章:工程实践——用 Claude-Mem 改造大型项目开发

4.1 场景一:跨月的重构任务

让我们通过一个真实场景理解 Claude-Mem 的价值。

场景:开发者正在重构一个 Node.js 后端服务,预计需要 3-4 周时间,分三个阶段:

第一阶段(Week 1):数据库层重构(ORM 迁移)
第二阶段(Week 2-3):API 层重构(REST → GraphQL)
第三阶段(Week 3-4):测试覆盖与部署优化

没有 Claude-Mem 的体验

  • Week 2 开始时,Claude Code 已经「忘记」了 Week 1 讨论过的 ORM 选型理由
  • 需要重新解释数据库表结构、迁移脚本位置、遇到的兼容性问题
  • 每次新会话都要粘贴大量上下文
  • Week 3 继续时,API 层的重构决策也要重新输入

有 Claude-Mem 的体验

Week 2 启动会话后,Claude-Mem 自动加载历史记忆:

📋 从历史会话中恢复了以下信息:
- ORM 迁移策略:Prisma → Drizzle(已于 Week 1 决策)
- 待迁移表清单:users, orders, products(12张表)
- 已知兼容性问题:旧脚本依赖 mysql2@3.x
- Week 1 完成:users, orders 表迁移完成

请继续 Week 2 任务:products 表迁移及 API 层准备

开发者无需重复输入上下文,Claude Code「记得」之前的所有讨论。

4.2 场景二:团队知识传承

Claude-Mem 的另一个高价值场景是团队知识传承

当新成员加入项目时,通常需要:

  1. 阅读大量文档和代码
  2. 与老成员进行多次 onboarding 对话
  3. 在使用 AI 助手时重复输入项目背景

Claude-Mem 可以通过导出/导入记忆文件,在团队成员之间共享上下文:

# 导出当前项目的记忆(供团队共享)
claude-mem export --project ./myapp --output ./team-memories/

# 生成的文件结构:
# team-memories/
#   ├── architecture.json    # 架构决策记录
#   ├── conventions.json     # 代码规范
#   ├── api-contracts.json   # API 契约
#   └── vector-index.bin     # 语义检索索引

新成员加入后:

# 导入团队记忆
claude-mem import --project ./myapp --source ./team-memories/

# 启动会话后自动加载:
# 📋 已加载团队共享记忆
# - 项目架构:Next.js + FastAPI + PostgreSQL
# - 代码规范:函数不超过 50 行,复杂逻辑必须写注释
# - API 认证:JWT + refresh token 机制
# - 当前 Sprint 目标:用户模块重构

4.3 场景三:多项目并行的上下文隔离

现代开发者经常同时维护多个项目。Claude-Mem 通过项目路径哈希实现完全隔离的记忆存储

# 每个项目有独立的记忆数据库
def get_project_db(project_path: str) -> str:
    project_hash = hashlib.sha256(
        realpath(project_path).encode()
    ).hexdigest()[:16]
    return f"{HOME}/.claude-mem/{project_hash}.db"

这确保了:

  • 项目 A 的记忆不会泄露到项目 B
  • 两个项目使用的相同技术栈不会互相干扰
  • 记忆加载时只加载当前项目的相关记忆

第五章:深层思考——记忆插件背后的商业博弈

5.1 为什么 Anthropic 没有自己做?

一个值得深思的问题是:上下文记忆明明是 Claude Code 的痛点,为什么 Anthropic 官方没有提供内置的跨会话记忆功能?

答案可能在于商业模型的权衡

Claude Code 的计费基于 Token 消耗。用户每次启动新会话并输入大量上下文时,都会消耗新的 Token。如果 Claude Code 提供内置的跨会话记忆,需要在服务端存储和同步这些记忆数据,这涉及:

  1. 数据存储成本:服务端存储用户的多会话记忆数据
  2. 隐私合规:用户的代码和项目上下文存储在第三方服务器
  3. 同步延迟:跨设备使用时需要数据同步
  4. 竞争护城河:记忆数据可能让用户更容易迁移到竞品

Claude-Mem 的出现恰好填补了这个空白——在本地解决记忆问题,不依赖服务端存储,不产生额外 Token 费用,不涉及隐私泄露。这是一套完全在用户本地运行的方案,对 Anthropic 来说是零成本的体验增强。

5.2 API 套利与上下文窗口的商业价值

Claude-Mem 的爆发式增长背后,还有一个不那么「纯粹技术」的因素:上下文窗口的商业价值

Anthropic 的 API 定价中,Token 消耗是核心计费维度。一个会话越长、上下文越丰富,Token 消耗就越大。Claude Code 的上下文压缩机制虽然减少了单会话内的 Token 消耗,但用户如果频繁开始新会话(因为每次新会话都需要重新输入上下文),总的 Token 消耗反而可能更高。

Claude-Mem 通过减少重复输入上下文的需求,间接降低了用户的 Token 总消耗。这对 Anthropic 的商业模式是一个微妙但真实的冲击。

这也解释了为什么 Claude-Mem 的爆火引发了行业讨论——它不仅是一个技术插件,更是一个在 LLM 商业模型裂缝中生长出来的「效率工具」,其背后的博弈值得整个行业思考。

5.3 开源 vs. 内置:开放生态的胜利

从更宏观的视角看,Claude-Mem 的成功是开源生态对封闭功能的又一次胜利。

Claude Code 的三层压缩策略是 Anthropic 的内置能力,用户只能被动接受。而 Claude-Mem 通过外部插件的方式,在不修改官方源码的前提下扩展了官方未能覆盖的功能。这种「用户需求驱动、社区快速迭代」的模式,是大型科技公司闭源产品难以复制的。

开源插件填补产品空白 → 用户需求得到满足 → 更多用户涌入 → 插件生态繁荣。这是一个正向飞轮,也是 AI 产品进化的重要路径。


第六章:性能优化与最佳实践

6.1 记忆质量调优

Claude-Mem 的默认配置对大多数场景足够好,但在特定场景下可以通过配置优化:

# ~/.claude-mem/config.yaml
memory:
  max_entries_per_project: 500     # 单项目最大记忆条目数
  importance_threshold: 0.45       # 低于此分数的内容不存储
  summarization_enabled: true       # 启用会话摘要
  summary_token_budget: 300         # 摘要最大 Token 数
  
retrieval:
  top_k: 8                          # 检索返回的最大条目数
  rerank_enabled: true              # 启用重排序
  
categories:
  - name: architecture
    weight: 1.5                    # 架构决策权重更高
  - name: api
    weight: 1.3
  - name: convention
    weight: 1.0
  - name: task
    weight: 0.8

6.2 存储空间管理

随着使用时间增长,记忆数据库会积累大量数据。Claude-Mem 提供了维护命令:

# 查看各项目的存储占用
claude-mem stats

# 输出示例:
# 项目:~/projects/ecommerce-api
#   记忆条目:234 条
#   向量索引:15.2 MB
#   最后更新:2 小时前
#
# 项目:~/projects/ml-pipeline
#   记忆条目:89 条
#   向量索引:6.8 MB
#   最后更新:3 天前

# 清理低价值记忆(访问次数少且分数低的条目)
claude-mem prune --project ~/projects/ml-pipeline --min-score 0.3

# 导出/备份
claude-mem backup --output ~/backups/claude-mem-$(date +%Y%m%d).zip

6.3 与其他工具的协同

Claude-Mem 可以与其他 AI 编程工具链形成协同效应:

工具组合协同效果
Claude-Mem + CLAUDE.md启动时双层上下文加载(静态项目说明 + 动态历史记忆)
Claude-Mem + Git记忆与版本历史关联,支持「根据 Git 历史解释代码变更」
Claude-Mem + Cursor跨 IDE 记忆共享(需要额外适配器)
Claude-Mem + Continue.dev支持 JetBrains/VS Code 的持久记忆

总结:记忆能力是 AI 编程助手的下一个分水岭

Claude Code 的三层压缩策略证明了 Claude Code 团队对长对话问题的深刻理解。但这套机制的边界在于:它只能在单会话内优化,无法突破会话边界

Claude-Mem 的出现填补了这个空白。通过本地向量存储 + 结构化 SQLite 的双轨架构、智能重要性评分、自动化会话摘要,Claude-Mem 让 Claude Code 获得了「跨会话持久记忆」的能力,开发者终于可以像对待真正的同事一样对待 AI 编程助手——你上次讨论的决策它记得,你之前解决的问题它不会重复问。

更深层的启示是:AI 编程助手的竞争已经从「模型能力」蔓延到「记忆与上下文管理」。当所有主流模型的代码生成能力趋于同质化时,谁能更好地管理和利用上下文,谁就能提供更连贯、更高效的开发体验。

Claude-Mem 不是终点,而是起点。记忆层的军备竞赛已经拉开帷幕——值得期待的是,这场竞赛的受益者,是每一个每天都在与代码搏斗的开发者。


参考资源

  • Claude-Mem GitHub: claude-mem/claude-mem
  • Anthropic 官方上下文管理指南
  • Claude Code 源码分析(CSDN 系列)
  • LangGraph 文档(多智能体框架的基础设施)

推荐文章

Python 微软邮箱 OAuth2 认证 Demo
2024-11-20 15:42:09 +0800 CST
File 和 Blob 的区别
2024-11-18 23:11:46 +0800 CST
markdown语法
2024-11-18 18:38:43 +0800 CST
JavaScript数组 splice
2024-11-18 20:46:19 +0800 CST
html一个全屏背景视频
2024-11-18 00:48:20 +0800 CST
Nginx 负载均衡
2024-11-19 10:03:14 +0800 CST
底部导航栏
2024-11-19 01:12:32 +0800 CST
使用 `nohup` 命令的概述及案例
2024-11-18 08:18:36 +0800 CST
程序员茄子在线接单