Linux软件包管理核心:APT原理、命令详解与故障排查指南
1. 项目概述为什么我们需要apt-get如果你刚开始接触 Linux尤其是像 Ubuntu、Debian 这样的发行版那么apt-get这个名字你肯定不陌生。它就像是你电脑里的“软件管家”但比任何图形界面的应用商店都更强大、更底层、也更可靠。我刚开始用 Linux 那会儿最头疼的就是装软件。在 Windows 上我们习惯了去官网下载一个.exe安装包双击、下一步、完成。但在 Linux 的世界里尤其是服务器环境这种“散装”安装方式会带来巨大的麻烦依赖关系混乱、版本冲突、卸载残留…… 直到我真正理解了apt-get及其背后的 APT 体系才感觉真正推开了 Linux 系统管理的大门。简单来说apt-get是 Advanced Packaging Tool (APT) 的一个核心命令行工具专门用于在 Debian 及其衍生系统如 Ubuntu、Linux Mint上处理软件的安装、升级和移除。它的核心价值在于解决软件依赖关系。比如你想安装一个文本编辑器vimvim本身可能依赖于libc6、libncurses等一堆共享库。apt-get的神奇之处在于它能自动分析出这些依赖并从配置好的软件源Repository里把所有需要的东西一次性下载、安装、配置好确保软件能正常运行。这背后是一套完整的软件包管理体系包括.deb格式的软件包、集中的软件仓库、以及维护得井井有条的依赖关系数据库。对于新手掌握apt-get是摆脱对图形界面依赖真正用命令行高效管理系统的第一步。对于运维和开发者它是自动化部署、环境搭建的基石。无论是想在 Ubuntu 20.04 上安装 ROS 开发环境 (sudo apt-get install ros-noetic-uvc-camera)还是给 Rocky Linux 配置静态 IP 所需的网络工具亦或是日常的linux系统更新都离不开它。接下来我们就深入这个“软件管家”的内部看看它到底怎么用以及如何避开那些新手常踩的坑。2. 核心原理APT 体系是如何运转的在动手敲命令之前花点时间理解 APT 的工作原理至关重要。这能让你在遇到“无法定位软件包”、“依赖关系不满足”这类错误时不再茫然而是能快速找到解决思路。你可以把整个 APT 体系想象成一个高度组织化的“超级市场”。2.1 软件源你的“货物仓库”这个“超级市场”的货架就是软件源。软件源本质上是一个或多个网络服务器上面存放着大量预先编译好的.deb软件包及其元数据索引。系统默认会配置好官方源如archive.ubuntu.com。这些源被记录在/etc/apt/sources.list文件以及/etc/apt/sources.list.d/目录下的额外清单文件中。一个典型的源条目长这样deb http://archive.ubuntu.com/ubuntu/ focal main restricted universe multiversedeb: 表示这是二进制软件包仓库。如果是deb-src则表示源代码包仓库。http://archive.ubuntu.com/ubuntu/: 仓库的 URL 地址。focal: 发行版代号Ubuntu 20.04 叫 Focal Fossa。这确保了软件版本的匹配。main restricted universe multiverse: 软件包的分类或组件。main是官方开源支持软件universe是社区维护开源软件restricted是专有设备驱动multiverse是有版权或法律限制的软件。注意修改软件源是优化下载速度、获取特定软件如某些最新版或国内镜像的常用操作。但切记要选择与系统版本匹配的源否则会导致版本混乱。国内用户常将官方源替换为阿里云、腾讯云、清华大学的镜像源以加速。2.2 本地数据库你的“库存清单”光有远程仓库还不够你的系统需要知道仓库里有什么、版本是多少、以及谁依赖谁。这就是apt-get update命令所做的事情。它会扫描/etc/apt/sources.list中配置的所有源下载最新的软件包列表索引如Packages.gz、Release文件并更新到本地的/var/lib/apt/lists/目录下。这个本地数据库记录了所有可用软件包的名称、版本、描述、依赖关系、冲突关系等信息。只有执行了apt-get update你的系统才知道软件仓库里最新的“库存”情况。如果你不更新就直接安装可能会因为本地信息过时而找不到软件包或者无法获取到最新的安全更新。2.3 依赖关系解析智能的“购物车”当你执行apt-get install vim时APT 会进行一系列复杂的计算查找包在本地数据库中找到名为vim的软件包。依赖分析读取vim的元数据发现它依赖libc6 ( 2.15)推荐vim-runtime等。冲突检查检查要安装的包是否与系统已安装的包冲突。解决方案计算生成一个事务Transaction计划列出所有需要新安装、升级或删除的软件包以满足vim及其所有依赖的要求。用户确认将这份计划展示给你询问是否继续。你同意后它才开始真正的下载和安装。这个过程完全自动化解决了手动管理依赖的噩梦。它也是apt-get系列命令install,remove,dist-upgrade的核心逻辑。3. 核心命令详解与实战操作理解了原理我们来看具体怎么用。apt-get的命令结构通常是sudo apt-get [选项] 命令 [软件包名]。使用sudo是因为安装软件需要 root 权限。3.1 基础维护命令保持系统健康更新软件包列表sudo apt-get update这是你最应该频繁运行的命令但常常被新手忽略。它不更新任何已安装的软件只更新本地软件包索引。建议在安装新软件或系统升级前都先运行一次。输出会显示“命中”、“获取”、“忽略”各个软件源并列出更新的包数量。升级已安装的软件包sudo apt-get upgrade这个命令会根据update刷新的列表将所有已安装的软件包升级到仓库中的最新版本。它会谨慎地处理依赖如果某个包的升级需要安装新包或删除现有包upgrade可能会跳过这个包的升级以保持系统稳定。这是最安全的日常更新方式。执行智能升级sudo apt-get dist-upgrade这个命令比upgrade更“激进”。它会处理因升级而产生的依赖关系变化智能地安装新依赖包或删除冲突的旧包。在跨次版本的系统升级时如从 Ubuntu 20.04 升级到 22.04或者需要跟随某些重大软件更新时会用到它。日常使用需谨慎最好先了解它会做什么变更。清理无用包sudo apt-get autoremove和sudo apt-get autocleanautoremove: 自动删除那些当初作为其他软件包的依赖被安装但现在已没有任何软件包依赖它们的“孤儿”包。这是释放磁盘空间的好习惯。autoclean: 清理本地缓存/var/cache/apt/archives/中已过时的.deb安装包文件即那些仓库中已有新版本的旧包。clean: 更彻底直接清空整个缓存目录。在你需要彻底清理空间或解决某些罕见的缓存问题时使用。3.2 软件生命周期管理安装、查找、移除安装软件sudo apt-get install package_name最常用的命令。你可以一次安装多个包用空格分隔。一些有用的选项-y或--yes: 自动对所有提示回答“是”常用于脚本中。--no-install-recommends: 不安装推荐的软件包只安装必须的依赖能让系统更精简。--install-suggests: 连建议的包也一并安装很少用。实战示例安装开发环境假设你想搭建一个 Python Web 开发环境可能会这样操作sudo apt-get update sudo apt-get install python3-pip python3-venv nginx postgresql一条命令所有依赖自动解决。模拟安装sudo apt-get install -s package_name-s选项代表“模拟”。它会运行完整的依赖解析和事务计算并打印出将要执行的操作安装、升级、删除哪些包但实际上不进行任何操作。在安装不熟悉的软件或进行重大系统变更前先用-s模拟一下是个非常棒的安全习惯。搜索软件包apt-cache search keyword注意搜索命令是apt-cache不是apt-get。它会在本地包数据库的描述信息中搜索关键词。例如想找一个叫htop的系统监控工具但不确定包名可以apt-cache search htop输出会列出所有包含“htop”的包及其简短描述。获取软件包详细信息apt-cache show package_name这个命令会显示指定软件包的详细信息包括版本、依赖、推荐、建议、描述、主页等。在安装前查看详情是个好习惯。移除软件sudo apt-get remove package_name移除指定的软件包但会保留其配置文件。这样如果你重新安装之前的配置还在。这是默认的、比较温和的卸载方式。彻底移除软件sudo apt-get purge package_name移除软件包并删除其配置文件。当你确定不再需要某个软件且想清除所有痕迹时使用。也可以结合使用sudo apt-get remove --purge package_name。实操心得对于像数据库MySQL/PostgreSQL、Web服务器Nginx/Apache这类有复杂配置的软件如果你打算彻底重装并从头配置可以用purge。如果只是暂时不用想保留配置以备后用用remove更安全。一个常见的坑是用remove卸载了桌面环境配置文件还在导致重新安装后一些奇怪的旧设置依然生效这时就需要purge来清理。3.3 故障排查与修复命令修复损坏的依赖sudo apt-get -f install-f是--fix-broken的缩写。当安装过程意外中断如断电、强制终止或者手动安装.deb包导致依赖关系断裂时系统可能会出现“有未满足的依赖关系”错误。运行此命令会尝试修复这些损坏的依赖关系通常能解决大部分安装错误。检查软件包状态dpkg -l | grep keyword虽然这不是apt-get命令但它是黄金搭档。dpkg -l列出所有已安装的.deb包的状态。结合grep可以快速查看某个软件是否已安装及其版本。状态栏的首字母很关键ii表示已正常安装。rc表示已卸载但配置文件残留即用了remove没purge。iU表示解压了但配置未完成可能安装中断。4. 高级技巧与最佳实践掌握了基本命令你已经能应对90%的场景。下面这些技巧能让你的效率再上一个台阶。4.1 使用apt更友好现代的替代品你可能也见过apt命令注意没有-get。它是apt-get、apt-cache等命令的一个更用户友好的前端。在 Ubuntu 16.04 及更高版本中推荐使用。它默认启用了颜色高亮、进度条并且一些常用操作更简洁。功能apt-get命令apt命令说明更新列表apt-get updateapt updateapt输出更简洁有颜色。安装软件apt-get install vimapt install vim功能完全相同。删除软件apt-get remove vimapt remove vim功能完全相同。搜索软件apt-cache search vimapt search vimapt整合了搜索功能。列出可升级包apt-get upgrade -s(模拟)apt list --upgradableapt的方式更直观。显示包详情apt-cache show vimapt show vim功能完全相同。个人建议在交互式命令行中使用apt体验更好。但在编写 Shell 脚本时为了兼容性和确定性apt-get的行为历史更久更稳定建议仍使用apt-get。4.2 处理“无法定位软件包”错误这是新手最高频的错误。原因和解决方案如下软件源列表未更新这是最常见的原因。首先运行sudo apt-get update。拼写错误Linux 包名通常全小写用连字符分隔。确认包名是否正确用apt-cache search辅助。软件源中不存在该软件可能不在你配置的软件源组件中。例如某些软件只在universe或multiverse组件里。检查/etc/apt/sources.list确保启用了相应的组件如focal main restricted universe multiverse。使用了错误的发行版代号如果你手动添加了第三方源如某些软件的官方 PPA源地址中的发行版代号如focal必须与你的系统版本匹配。用lsb_release -c查看你的代号。软件太新或太旧你要安装的软件版本可能尚未进入稳定的软件源或者你的系统版本太老软件已移出旧源。这时可能需要添加官方或第三方的 PPA个人软件包存档。4.3 添加和移除 PPAPPA 是 Ubuntu 独有的概念由 Launchpad 提供服务允许个人或团队构建并发布软件包。它是获取最新软件版本的重要渠道。添加 PPAsudo add-apt-repository ppa:user/ppa-name sudo apt-get update例如添加一个著名的图形驱动 PPAsudo add-apt-repository ppa:graphics-drivers/ppa移除 PPAsudo add-apt-repository --remove ppa:user/ppa-name sudo apt-get update或者直接删除/etc/apt/sources.list.d/目录下对应的.list文件再执行update。重要警告PPA 并非官方源其软件包的稳定性、安全性和兼容性由维护者负责。添加来源不明的 PPA 有引入系统不稳定甚至安全风险的可能。只添加你信任的、知名的 PPA。4.4 下载但不安装软件包有时你需要将软件包及其依赖下载到本地以便在离线环境中安装。sudo apt-get install --download-only package_name所有.deb包会被下载到/var/cache/apt/archives/。你可以将这些文件复制到离线机器上然后使用sudo dpkg -i *.deb进行安装可能需要手动处理依赖使用sudo dpkg -i *.deb后若报错可尝试sudo apt-get -f install修复。4.5 锁定软件包版本在生产服务器上你可能希望禁止某个关键软件如内核、数据库自动升级以防止意外变更导致服务中断。使用apt-marksudo apt-mark hold package_name # 锁定包阻止其被升级 sudo apt-mark unhold package_name # 解除锁定 sudo apt-mark showhold # 显示所有被锁定的包被hold的包在执行apt-get upgrade时会被跳过。5. 常见问题与排查技巧实录即使理解了原理和命令在实际操作中还是会遇到各种问题。这里记录了几个我踩过的坑和解决方案。5.1 依赖地狱依赖关系被破坏或有未满足的依赖关系场景安装或升级时终端爆出一大片红色错误提示依赖问题。排查步骤首选修复命令立刻尝试sudo apt-get -f install。这个命令专为修复依赖而设计成功率很高。检查软件源状态运行sudo apt-get update观察是否有源连接失败或哈希校验失败。这可能是网络问题或源地址失效。可以暂时注释掉有问题的源在/etc/apt/sources.list行首加#。使用dpkg诊断运行sudo dpkg --configure -a尝试完成任何未完成的包配置过程。终极清理与重建如果上述方法无效可以尝试更激进的步骤谨慎操作最好有备份# 清理可能损坏的状态信息 sudo rm -rf /var/lib/apt/lists/* sudo apt-get clean # 重建软件源列表 sudo apt-get update # 尝试修复 sudo apt-get -f install sudo apt-get upgrade --fix-missing5.2E: 无法获得锁 /var/lib/dpkg/lock-frontend场景执行apt-get命令时提示无法获得锁。原因这表示另一个包管理进程如apt、dpkg、synaptic或软件更新器正在运行锁定了 APT 的数据库。解决等待最简单的方法等几分钟让前一个进程完成。找出并结束进程使用ps aux | grep apt或ps aux | grep dpkg找到相关进程用sudo kill PID结束它。但需小心强制终止可能使包管理处于不一致状态。删除锁文件最后手段sudo rm /var/lib/apt/lists/lock sudo rm /var/lib/dpkg/lock sudo rm /var/cache/apt/archives/lock删除后再运行sudo apt-get update。注意这应在你确认没有其他包管理程序在运行时进行。5.3 安装特定版本软件默认apt-get install会安装仓库中最新的稳定版。但有时你需要安装特定版本如降级以解决兼容性问题。首先查看可用版本apt-cache policy package_name输出会显示已安装的版本、候选版本以及所有可用版本及其对应的软件源。安装指定版本sudo apt-get install package_nameversion例如sudo apt-get install nginx1.18.0-0ubuntu15.4 空间不足导致安装失败安装软件需要下载包缓存和解压安装的空间。如果/boot存放内核或根分区/空间不足会失败。排查使用df -h查看各分区使用情况。对于/boot分区通常是因为旧内核积累过多。使用sudo apt-get autoremove --purge可以移除旧内核包。对于根分区清理 APT 缓存sudo apt-get clean清理所有缓存或sudo apt-get autoclean清理旧版本缓存。5.5 与 Snap/Flatpak 等其他包格式共存现代 Linux 系统除了 APT可能还有 SnapUbuntu 推广或 Flatpak。它们相互独立。一个软件可能有.deb、Snap、Flatpak 多种安装方式。建议优先使用 APT它最深度集成于系统性能最好管理最方便。Snap/Flatpak 作为补充当 APT 源中没有某个软件的最新版或者你需要更好的沙盒隔离、跨发行版兼容性时可以考虑。例如安装最新的 IDE 或图形工具。避免混用不要用 APT 和 Snap 安装同一个软件的不同版本这可能导致冲突。用which command查看命令来自哪个包管理器。掌握apt-get不仅仅是记住几个命令更是理解 Debian/Ubuntu 系统生态的基石。从最初的敲命令装软件到后来写脚本批量部署环境再到排查复杂的依赖冲突它始终是最可靠的工具。我个人的习惯是在任何安装操作前先update在不确定时用-s模拟定期autoremove保持系统整洁对于生产环境谨慎使用dist-upgrade并对关键包做hold。把这些习惯融入日常Linux 系统的管理会变得清晰而高效。

相关新闻

C++之string和char的使用及区别

C++之string和char的使用及区别

一、概念Char:在C中,char是定义一个字符,存储的是一个字符,占一个字节,如’a’,C中char是字符类型,是一种基本数据类型;String:string是一个模板类,实例化的是对象&#…

2026/10/16 9:53:55 阅读更多 →
C++ class传值和传引用的详细介绍

C++ class传值和传引用的详细介绍

在 C 中,class(类对象)的传值和传引用是两种截然不同的参数传递方式,它们在性能、内存管理和行为上有着本质的区别。简单来说:传值是“复制一份”,传引用是“取个别名”。以下是详细的对比分析:…

2026/10/20 3:27:00 阅读更多 →
恋活HF Patch补丁怎么装?200+插件一键解锁汉化、去码与场景创作

恋活HF Patch补丁怎么装?200+插件一键解锁汉化、去码与场景创作

恋活HF Patch补丁怎么装?200插件一键解锁汉化、去码与场景创作 【免费下载链接】KK-HF_Patch Automatically translate, uncensor and update Koikatu! and Koikatsu Party! 项目地址: https://gitcode.com/gh_mirrors/kk/KK-HF_Patch 你是不是也遇到过&…

2026/10/19 5:39:11 阅读更多 →

最新新闻

专科生论文降AI率实战指南:九款降AIGC工具测评与避坑要点

专科生论文降AI率实战指南:九款降AIGC工具测评与避坑要点

最近后台问得最多的不是论文怎么写,而是“论文写完了AI率太高怎么办”。很多专科生现在交课程论文、毕业设计、实习报告之前,都要先跑一遍AIGC检测,结果一出来就慌了:明明是自己查阅资料写的初稿,只是用AI帮忙润了润色…

2026/10/20 11:32:30 阅读更多 →
三种count

三种count

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 11:32:30 阅读更多 →
ThinkPHP免签支付系统搭建与安全实践指南

ThinkPHP免签支付系统搭建与安全实践指南

简介:这是一套基于ThinkPHP8框架开发的个人免签收款系统源码,面向个体商户、小微开发者及PHP学习者,解决普通收款码无法自动回调通知、缺乏自主收款后台的痛点,适用于微信/支付宝个人码快速接入商城、知识付费、小程序后端等轻量级…

2026/10/20 11:32:30 阅读更多 →
Transformer单轮对话机器人源码解析与训练调优实战

Transformer单轮对话机器人源码解析与训练调优实战

简介:这是一套基于Transformer架构的单轮对话聊天机器人完整项目,面向Python开发者、NLP初学者以及需要完成毕业设计或课程设计的在校学生。资源内含可直接运行的Python源码、已训练好的词表与小规模模型文件,并配套详细项目使用说明&#xf…

2026/10/20 11:32:30 阅读更多 →
智能客服两大核心模块:问题解答与投诉处理的落地实践

智能客服两大核心模块:问题解答与投诉处理的落地实践

做智能客服项目这几年,我最大的感受是:“问题解答”和“投诉处理”这两个模块,看着简单,真正做得好的项目没几个。很多团队把精力全花在对话界面上,结果系统上线之后,用户问一句常规问题答非所问&#xff0…

2026/10/20 11:32:30 阅读更多 →
PaddleOCR打包EXE离线部署:CPU/GPU自动切换与模型热更新

PaddleOCR打包EXE离线部署:CPU/GPU自动切换与模型热更新

简介:本资源是一个基于PaddleOCR构建的离线文字识别工具打包成品,面向无Python运行环境的终端用户及希望快速部署OCR能力的开发者。它解决了在受限系统(如客户机、内网办公机)中无法安装依赖、调用模型的痛点,仅需双击…

2026/10/20 11:31:29 阅读更多 →

日新闻

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
ESP32舵机控制指南:原理、多路驱动与避坑实战

ESP32舵机控制指南:原理、多路驱动与避坑实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
位移法实现一阶低通滤波:单片机ADC采样降噪实战

位移法实现一阶低通滤波:单片机ADC采样降噪实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/20 10:02:13 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/19 17:32:41 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 10:02:08 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:17 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:45 阅读更多 →