{ "meta": { "version": "4.0", "title": "Linux 系统学习课程(重构版)", "author": "OpenClaw Dev", "updated": "2026-03-10", "description": "强调知识理解、场景迁移与轻量练习的 Linux 学习课程", "module_count": 6, "total_lessons": 18, "total_exercises": 54 }, "modules": [ { "id": "module_1_foundation", "title": "模块 1:建立 Linux 基本认知", "summary": "先理解终端、目录、路径和最基础命令,建立 Linux 使用的空间感。", "lessons": [ { "id": "m1_l1_pwd", "title": "认识当前目录:pwd", "goal": "理解当前工作目录的意义,知道自己在文件系统中的位置。", "why_it_matters": "很多 Linux 操作依赖路径。如果不知道自己当前在哪,后续命令容易出错。", "concepts": [ "当前工作目录", "绝对路径与相对路径", "为什么要先定位再操作" ], "command": "pwd", "examples": [ "pwd", "cd /tmp && pwd" ], "pitfalls": [ "以为终端默认总在同一个目录", "不分清当前目录和目标目录" ], "scenarios": [ "切目录后确认自己到了哪里", "写脚本前确认当前运行位置" ], "exercises": [ { "id": "m1_l1_e1", "type": "understanding", "question": "查看当前工作目录应该使用什么命令?", "answer": "pwd" }, { "id": "m1_l1_e2", "type": "operation", "title": "输出当前目录", "hint": "直接输入 pwd", "success_test": "cmd == 'pwd'", "solution": ["pwd"], "success_msg": "你已经能确认自己所在的位置了。" }, { "id": "m1_l1_e3", "type": "scenario", "question": "如果你不确定自己当前在哪个目录,第一反应应该做什么?", "answer": "先执行 pwd 确认当前目录" } ] }, { "id": "m1_l2_ls", "title": "看见目录内容:ls", "goal": "理解 ls 的作用,并掌握查看隐藏文件和详细信息的基本方式。", "why_it_matters": "Linux 下很多探索行为都从 ls 开始,它决定你如何观察目录结构。", "concepts": [ "目录内容查看", "隐藏文件", "长列表信息" ], "command": "ls", "examples": [ "ls", "ls -la", "ls -lh /etc" ], "pitfalls": [ "误以为 ls 看不到的文件就不存在", "不会区分普通 ls 和 ls -l 的用途" ], "scenarios": [ "排查目录里到底有哪些文件", "检查配置目录中是否有隐藏文件" ], "exercises": [ { "id": "m1_l2_e1", "type": "understanding", "question": "为什么 ls -a 会比 ls 多看到一些文件?", "answer": "因为它会显示隐藏文件,包括以点开头的文件" }, { "id": "m1_l2_e2", "type": "operation", "title": "列出当前目录内容", "hint": "输入 ls", "success_test": "cmd == 'ls'", "solution": ["ls"], "success_msg": "你已经会观察目录内容了。" }, { "id": "m1_l2_e3", "type": "operation", "title": "显示隐藏文件和详细信息", "hint": "使用 ls -la", "success_test": "cmd == 'ls -la' or cmd == 'ls -al'", "solution": ["ls -la", "ls -al"], "success_msg": "你已经会用更完整的方式查看目录了。" } ] }, { "id": "m1_l3_cd_cat_echo", "title": "移动、读文件、输出文本", "goal": "掌握 cd、cat、echo 这些最基础但最常用的命令。", "why_it_matters": "这三个命令几乎贯穿 Linux 入门阶段的所有练习。", "concepts": [ "切换目录", "读取文件", "输出文本与变量" ], "command": "cd / cat / echo", "examples": [ "cd /tmp", "cat /etc/hosts", "echo Hello Linux" ], "pitfalls": [ "把 cd 和 ls 混用", "用 cat 去看过大的文件", "不知道 echo 也常用于脚本调试" ], "scenarios": [ "进入指定目录继续操作", "快速读取配置文件", "验证变量和命令输出" ], "exercises": [ { "id": "m1_l3_e1", "type": "operation", "title": "进入 /tmp 目录", "hint": "cd /tmp", "success_test": "cmd == 'cd /tmp' and cwd == '/tmp'", "solution": ["cd /tmp"], "success_msg": "你已经能切换到目标目录了。" }, { "id": "m1_l3_e2", "type": "operation", "title": "读取 hosts 文件", "hint": "cat /etc/hosts", "success_test": "cmd == 'cat /etc/hosts' and 'localhost' in output", "solution": ["cat /etc/hosts"], "success_msg": "你已经会读取基础文本文件了。" }, { "id": "m1_l3_e3", "type": "operation", "title": "输出 Hello Linux", "hint": "echo Hello Linux", "success_test": "cmd == 'echo Hello Linux' and 'Hello Linux' in output", "solution": ["echo Hello Linux"], "success_msg": "你已经掌握了最基础的文本输出命令。" } ] } ] }, { "id": "module_2_filesystem", "title": "模块 2:文件与目录操作", "summary": "围绕创建、复制、移动、删除和查看文件属性建立文件系统操作能力。", "lessons": [ { "id": "m2_l1_create", "title": "创建文件与目录:mkdir / touch", "goal": "理解目录和文件的创建逻辑,学会递归创建多级目录。", "why_it_matters": "很多项目初始化、环境准备都从创建目录结构开始。", "concepts": ["目录创建", "多级目录", "空文件创建"], "command": "mkdir / touch", "examples": ["mkdir demo", "mkdir -p /tmp/a/b/c", "touch notes.txt"], "pitfalls": ["忘记使用 -p 创建多级目录", "目标父目录不存在时 touch 失败"], "scenarios": ["初始化项目目录结构", "创建占位文件和日志文件"], "exercises": [ {"id": "m2_l1_e1", "type": "operation", "title": "递归创建目录", "hint": "mkdir -p /tmp/a/b/c", "success_test": "cmd == 'mkdir -p /tmp/a/b/c' and exists('/tmp/a/b/c')", "solution": ["mkdir -p /tmp/a/b/c"], "success_msg": "多级目录创建成功。"}, {"id": "m2_l1_e2", "type": "operation", "title": "创建空文件", "hint": "touch /tmp/a/b/c/readme.txt", "success_test": "cmd == 'touch /tmp/a/b/c/readme.txt' and exists('/tmp/a/b/c/readme.txt')", "solution": ["touch /tmp/a/b/c/readme.txt"], "success_msg": "空文件创建成功。"}, {"id": "m2_l1_e3", "type": "scenario", "question": "为什么 mkdir -p 适合项目初始化?", "answer": "因为它可以一次创建多级目录,即使上层目录不存在也能自动补齐"} ] }, { "id": "m2_l2_move_copy_delete", "title": "复制、移动与删除:cp / mv / rm", "goal": "理解文件操作中的备份、迁移、重命名和清理。", "why_it_matters": "日常 Linux 使用里最常见的就是处理文件的生命周期。", "concepts": ["复制与备份", "移动与重命名", "删除风险"], "command": "cp / mv / rm", "examples": ["cp /etc/hosts /tmp/hosts.bak", "mv old.txt new.txt", "rm -r /tmp/testdir"], "pitfalls": ["把删除当成移动", "对目录使用 cp 却忘记 -r", "rm -rf 风险极高"], "scenarios": ["做配置备份", "整理日志文件", "清理无用目录"], "exercises": [ {"id": "m2_l2_e1", "type": "operation", "title": "复制 hosts 文件", "hint": "cp /etc/hosts /tmp/hosts.bak", "success_test": "cmd == 'cp /etc/hosts /tmp/hosts.bak' and exists('/tmp/hosts.bak')", "solution": ["cp /etc/hosts /tmp/hosts.bak"], "success_msg": "文件备份成功。"}, {"id": "m2_l2_e2", "type": "operation", "title": "重命名备份文件", "hint": "mv /tmp/hosts.bak /tmp/hosts.backup", "success_test": "cmd == 'mv /tmp/hosts.bak /tmp/hosts.backup' and exists('/tmp/hosts.backup')", "solution": ["mv /tmp/hosts.bak /tmp/hosts.backup"], "success_msg": "文件重命名成功。"}, {"id": "m2_l2_e3", "type": "understanding", "question": "为什么 rm -rf 是高风险命令?", "answer": "因为它会递归并强制删除文件和目录,执行错误会造成不可恢复的数据丢失"} ] }, { "id": "m2_l3_stat_permissions", "title": "认识文件属性:stat 与权限基础", "goal": "开始理解文件属性和权限表达。", "why_it_matters": "文件权限是 Linux 系统安全和协作的重要基础。", "concepts": ["文件元信息", "权限三元组", "目录与文件权限差异"], "command": "stat / chmod", "examples": ["stat /etc/hosts", "chmod 755 script.sh", "chmod +x run.sh"], "pitfalls": ["不了解 755 / 644 的含义", "给不该执行的文件随意加执行权限"], "scenarios": ["检查脚本是否可执行", "排查权限导致的运行失败"], "exercises": [ {"id": "m2_l3_e1", "type": "operation", "title": "查看 hosts 属性", "hint": "stat /etc/hosts", "success_test": "cmd == 'stat /etc/hosts' and 'File:' in output", "solution": ["stat /etc/hosts"], "success_msg": "你已经会查看文件属性了。"}, {"id": "m2_l3_e2", "type": "understanding", "question": "755 和 644 最核心的区别是什么?", "answer": "755 允许拥有者读写执行,其他人读执行;644 没有执行权限"}, {"id": "m2_l3_e3", "type": "operation", "title": "给文件添加执行权限", "hint": "chmod +x /tmp/a/b/c/readme.txt", "success_test": "cmd == 'chmod +x /tmp/a/b/c/readme.txt'", "solution": ["chmod +x /tmp/a/b/c/readme.txt"], "success_msg": "你已经完成了权限修改练习。"} ] } ] }, { "id": "module_3_searching", "title": "模块 3:阅读与筛选信息", "summary": "把 Linux 当成信息检索工具来学,围绕日志、配置和统计建立阅读能力。", "lessons": [ { "id": "m3_l1_read_logs", "title": "看文件头尾:head / tail", "goal": "学会快速读取大文件的局部内容。", "why_it_matters": "日志通常很大,不可能总是整份去看。", "concepts": ["查看前几行", "查看后几行", "实时追踪"], "command": "head / tail", "examples": ["head -n 5 /var/log/syslog", "tail -n 20 /var/log/syslog", "tail -f /var/log/syslog"], "pitfalls": ["大文件直接 cat 影响阅读效率", "不会区分查看历史和跟踪新增日志"], "scenarios": ["看配置文件开头", "盯日志尾部排查实时错误"], "exercises": [ {"id": "m3_l1_e1", "type": "operation", "title": "查看 syslog 前 5 行", "hint": "head -n 5 /var/log/syslog", "success_test": "(cmd == 'head -n 5 /var/log/syslog' or cmd == 'head -5 /var/log/syslog') and len(output.split('\n')) >= 5", "solution": ["head -n 5 /var/log/syslog", "head -5 /var/log/syslog"], "success_msg": "你已经会局部查看大文件开头了。"}, {"id": "m3_l1_e2", "type": "operation", "title": "查看 syslog 最后 3 行", "hint": "tail -n 3 /var/log/syslog", "success_test": "(cmd == 'tail -n 3 /var/log/syslog' or cmd == 'tail -3 /var/log/syslog') and len(output.split('\n')) >= 3", "solution": ["tail -n 3 /var/log/syslog", "tail -3 /var/log/syslog"], "success_msg": "你已经会快速查看日志尾部了。"}, {"id": "m3_l1_e3", "type": "scenario", "question": "为什么排查线上报错时更常先用 tail 而不是 cat?", "answer": "因为日志通常很大,tail 可以更快聚焦最近发生的问题"} ] }, { "id": "m3_l2_grep", "title": "关键词搜索:grep", "goal": "理解 grep 作为日志排障和文本定位核心工具的价值。", "why_it_matters": "没有 grep,查日志和配置会慢很多。", "concepts": ["大小写忽略", "显示行号", "反向匹配", "递归搜索"], "command": "grep", "examples": ["grep error /var/log/syslog", "grep -in root /etc/passwd", "grep -v nologin /etc/passwd"], "pitfalls": ["不会结合 -n 定位行号", "不知道 -i 和 -v 的常见用途"], "scenarios": ["查错误日志", "找配置项", "过滤无效行"], "exercises": [ {"id": "m3_l2_e1", "type": "operation", "title": "查找 syslog 中的 error", "hint": "grep error /var/log/syslog", "success_test": "cmd == 'grep error /var/log/syslog' and 'error' in output.lower()", "solution": ["grep error /var/log/syslog"], "success_msg": "你已经会在日志里搜关键词了。"}, {"id": "m3_l2_e2", "type": "operation", "title": "忽略大小写搜索 root", "hint": "grep -i root /etc/passwd", "success_test": "cmd == 'grep -i root /etc/passwd'", "solution": ["grep -i root /etc/passwd"], "success_msg": "你已经知道如何处理大小写差异了。"}, {"id": "m3_l2_e3", "type": "understanding", "question": "grep -n 的意义是什么?", "answer": "显示匹配结果所在的行号,方便快速定位原文位置"} ] }, { "id": "m3_l3_find_wc_sort", "title": "查找与统计:find / wc / sort", "goal": "建立查找文件和做基础统计的能力。", "why_it_matters": "Linux 的很多效率来自组合式查找与统计。", "concepts": ["按名称查找", "行数字数统计", "排序输出"], "command": "find / wc / sort", "examples": ["find /etc -name '*.conf'", "wc -l /var/log/syslog", "ls | sort"], "pitfalls": ["把 find 和 grep 混淆", "不会根据任务选文件查找还是内容查找"], "scenarios": ["找配置文件", "统计日志行数", "整理输出结果"], "exercises": [ {"id": "m3_l3_e1", "type": "operation", "title": "查找 /etc 下所有 .conf 文件", "hint": "find /etc -name '*.conf'", "success_test": "cmd == \"find /etc -name '*.conf'\" and '.conf' in output", "solution": ["find /etc -name '*.conf'"], "success_msg": "你已经会用 find 定位文件了。"}, {"id": "m3_l3_e2", "type": "operation", "title": "统计 syslog 行数", "hint": "wc -l /var/log/syslog", "success_test": "cmd == 'wc -l /var/log/syslog' and output.strip().isdigit()", "solution": ["wc -l /var/log/syslog"], "success_msg": "你已经会做基础统计了。"}, {"id": "m3_l3_e3", "type": "understanding", "question": "找文件位置应该优先想到 find 还是 grep?为什么?", "answer": "优先用 find,因为这是文件定位问题,不是文件内容搜索问题"} ] } ] } ] }