简介本资源是面向C/C嵌入式及桌面应用开发者的SQLite3轻量级数据库集成工具包专为需要快速接入本地数据存储能力的中初级开发者设计。压缩包内含8个文件4个静态库含Unicode/多字节、Release/Debug多线程版本、2个头文件sqlite3.h与封装类Sqlite3_ls65.h、1个C实现文件Sqlite3_ls65.cpp及1份使用说明文档总大小1.68MB结构精炼、开箱即用。已有203人学习下载反映出其在小型项目快速落地场景中的实用价值。读者可直接将头文件纳入工程路径按需链接对应.lib文件或基于已封装的C类简化数据库操作说明.txt还提供了配置指引与典型用法示例显著降低SQLite3原生API的学习门槛与集成成本。1. Sqlite3-static.7z一个被低估的“零依赖”嵌入式数据库交付包专治部署环境混乱、glibc版本冲突、容器镜像臃肿你有没有遇到过这样的场景在某台老旧 CentOS 6 服务器上跑一个 Python 脚本脚本里用pysqlite3操作本地数据库结果一执行就报ImportError: libsqlite3.so.0: cannot open shared object file或者在 Alpine Linux 容器里构建 Go 程序链接时提示undefined reference to sqlite3_open_v2翻遍文档才发现 Alpine 默认不带-dev包而 musl libc 下编译动态链接版 sqlite3 又极易出错又或者你在做离线交付——给客户一台断网的工控机部署边缘采集服务要求“拷过去就能跑”但系统连apt或yum都没有更别说自己编译 sqlite3 了Sqlite3-static.7z 就是为这类真实、高频、让人抓狂的交付现场准备的它不是源码不是安装包而是一个预编译、全静态链接、无外部运行时依赖、开箱即用的 sqlite3 命令行二进制集合。它不替换系统 sqlite3也不动环境变量只提供一个干净、确定、可验证的sqlite3可执行文件以及配套的.so用于 dlopen 场景和头文件用于交叉编译。适合嵌入式开发者、边缘计算部署工程师、离线系统集成商、以及所有厌倦了“为什么我本地好好的线上就挂”的一线实施人员。2. 为什么必须用 static 版本从动态链接的“黑匣子”说起2.1 动态链接 sqlite3 的三大隐性成本动态链接版 sqlite3如系统自带的/usr/bin/sqlite3或pip install pysqlite3安装的看似省事实则埋着三颗雷glibc 版本锁死/lib64/libc.so.6的 ABI 兼容性极差。CentOS 7 的 glibc 2.17 编译的二进制在 CentOS 6glibc 2.12上直接Segmentation fault反过来低版本编译的在高版本上可能缺符号。这不是 bug是 C 库演进的必然代价。扩展模块不可控json1、fts5、rtree这些实用扩展是否启用、是否编译进libsqlite3.so完全取决于发行版打包策略。Ubuntu 可能默认开fts5Alpine 可能只留json1而你的 SQL 脚本一旦用了MATCH语法就当场报错no such module: fts5。加载路径玄学LD_LIBRARY_PATH、/etc/ld.so.conf.d/、rpath、RUNPATH……这些机制在容器、chroot、非 root 用户下极易失效。你strace一下sqlite3 --version常能看到它徒劳地在/usr/local/lib、/opt/lib、$HOME/lib里反复openat(AT_FDCWD, ..., O_RDONLY|O_CLOEXEC) -1 ENOENT最后才 fallback 到/lib64——这个过程不可预测且无法在部署前验证。提示ldd /usr/bin/sqlite3是诊断的第一步。如果输出里有libsqlite3.so.0 not found或指向/usr/lib/x86_64-linux-gnu/libsqlite3.so.0这类路径说明它依赖外部共享库——这正是 static 版要消灭的对象。2.2 Static 编译的核心技术选型musl-gcc SQLite3 官方 amalgamationSqlite3-static.7z 的构建链路非常克制只依赖两个确定性极强的组件musl-gcc 工具链不是 glibc而是 musl libc。musl 的设计哲学就是“最小化、确定性、无隐式依赖”。它不实现gethostbyname_r这类 POSIX 边缘函数不兼容 glibc 的__libc_start_mainhook但换来的是一个静态链接的二进制只要 CPU 架构匹配x86_64/arm64就能在任何 Linux 发行版上运行包括最精简的 initramfs。SQLite3 Amalgamation 源码官方提供的sqlite3.c单文件聚合体。它把sqlite3.h、parse.c、tokenize.c、vdbe.c等上百个源文件全部预处理合并消除了#include路径问题和编译顺序依赖。我们用gcc -static -Os -fPIC -D SQLITE_ENABLE_JSON1 -D SQLITE_ENABLE_FTS5 -D SQLITE_ENABLE_RTREE -D SQLITE_ENABLE_COLUMN_METADATA ...直接编译这个单文件生成sqlite3和libsqlite3.a。没有 autotools没有 configure 脚本没有--enable-xxx的模糊开关——所有功能开关都在编译宏里写死可审计、可复现。2.3 文件结构解析不只是一个sqlite3二进制解压Sqlite3-static.7z后你会看到清晰的三层结构sqlite3-static/ ├── bin/ │ └── sqlite3 # 主程序全静态 x86_64 二进制大小约 1.2MB ├── lib/ │ ├── libsqlite3.a # 静态库供你自己的 C/C 项目链接 │ └── libsqlite3.so # 全静态 .sodlopen() 可加载无 .so.0 后缀避免版本劫持 └── include/ └── sqlite3.h # 头文件与官方 3.45.1 版本严格对齐注意libsqlite3.so的特殊性它不是动态库而是用gcc -shared -static生成的“伪动态库”。它内部不依赖任何.soldd libsqlite3.so输出为not a dynamic executable但它支持dlopen(libsqlite3.so, RTLD_LAZY)—— 这对 Python 的ctypes.CDLL()、Go 的plugin.Open()、Rust 的libloading都至关重要。很多用户误以为 static 就只能用libsqlite3.a其实libsqlite3.so才是跨语言集成的黄金通道。3. 四种典型落地场景从命令行到嵌入式 C手把手实操3.1 场景一替代系统 sqlite3修复老旧服务器的缺失依赖假设你有一台运行CentOS 6.10内核 2.6.32glibc 2.12的采集服务器/usr/bin/sqlite3早已被删且yum install sqlite会报No package sqlite available因为 CentOS 6 的 sqlite 包名是sqlite2不兼容。此时# 步骤1下载并解压假设已上传 Sqlite3-static.7z 到 /tmp 7z x /tmp/Sqlite3-static.7z -o/tmp/sqlite3-static # 步骤2创建软链接覆盖 PATH不修改系统 /usr/bin安全 sudo ln -sf /tmp/sqlite3-static/bin/sqlite3 /usr/local/bin/sqlite3 # 步骤3验证——检查是否真静态 ldd /usr/local/bin/sqlite3 # 应输出 not a dynamic executable /usr/local/bin/sqlite3 --version # 输出 3.45.1 2024-03-12 11:06:23 ...参数说明-o/tmp/sqlite3-static是 7z 的解压目标目录/usr/local/bin在绝大多数$PATH中排在/usr/bin之前因此which sqlite3会优先命中它。此操作无需 root 权限即可完成用户级 PATH 修改但软链接需 sudo。3.2 场景二在 Alpine Linux 容器中嵌入 SQLite3构建最小化镜像Alpine 的apk add sqlite安装的是动态链接版体积小但依赖musl和libstdc且fts5扩展默认关闭。用 static 版可做到5MB 镜像# Dockerfile FROM alpine:3.19 # 步骤1安装 7z 解压工具比 tar 更可靠处理 .7z RUN apk add --no-cache p7zip-full # 步骤2下载并解压 static 包此处用 curl生产环境建议 COPY 内部存储 RUN curl -sL https://example.com/Sqlite3-static.7z | 7z x -si -o/sqlite3-static # 步骤3将 bin/ 加入 PATH并清理安装包 ENV PATH/sqlite3-static/bin:$PATH RUN rm -rf /sqlite3-static/lib /sqlite3-static/include /tmp/* # 步骤4验证构建时执行 RUN sqlite3 --version \ echo CREATE VIRTUAL TABLE t USING fts5(x); | sqlite3 :memory: \ echo ✅ fts5 works || exit 1关键点-si表示从 stdin 读取数据流避免写临时文件/sqlite3-static/bin加入PATH后后续所有RUN和最终容器内的sqlite3命令都自动使用 static 版。echo ... | sqlite3 :memory:是验证fts5是否生效的黄金命令——动态版 Alpine sqlite3 默认不编译此扩展。3.3 场景三C 项目中静态链接生成真正单文件可执行程序你有一个采集数据并写入 SQLite 的 C 程序logger.c要求交付给客户时只有一个二进制不附带任何.so// logger.c #include stdio.h #include sqlite3.h int main(int argc, char *argv[]) { sqlite3 *db; char *err_msg 0; int rc sqlite3_open_v2(data.db, db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0); if (rc ! SQLITE_OK) { fprintf(stderr, Cannot open database: %s\n, sqlite3_errmsg(db)); return 1; } // ... 插入逻辑 sqlite3_close(db); return 0; }编译命令关键必须用 static 链接# 假设 Sqlite3-static.7z 解压在 ~/deps/ gcc -Os -static \ -I~/deps/sqlite3-static/include \ logger.c \ -L~/deps/sqlite3-static/lib \ -lsqlite3 \ -o logger-static # 验证ldd logger-static 必须显示 not a dynamic executable # 运行./logger-static —— 无论目标机器是否有 sqlite3都能跑参数说明-static是 GCC 的全局静态链接开关它强制所有库包括 libc都用.a-I指定头文件路径-L指定库路径-lsqlite3会自动找到libsqlite3.a。注意不要加-lpthread或-ldlmusl libc 已内置这些功能。3.4 场景四Python ctypes 动态加载绕过 pysqlite3 的版本绑定pysqlite3是 Python 的 sqlite3 绑定但它硬编码了libsqlite3.so.0的 soname且无法启用fts5。用 static 的libsqlite3.so可完全接管# load_static_sqlite.py import ctypes import os # 步骤1加载 static 版 libsqlite3.so绝对路径 lib_path /path/to/sqlite3-static/lib/libsqlite3.so sqlite_lib ctypes.CDLL(lib_path) # 步骤2定义函数签名关键否则调用会 segfault sqlite_lib.sqlite3_open_v2.argtypes [ctypes.c_char_p, ctypes.POINTER(ctypes.c_void_p), ctypes.c_int, ctypes.c_char_p] sqlite_lib.sqlite3_open_v2.restype ctypes.c_int sqlite_lib.sqlite3_close.argtypes [ctypes.c_void_p] sqlite_lib.sqlite3_close.restype ctypes.c_int # 步骤3调用传 bytes不是 str db_ptr ctypes.c_void_p() rc sqlite_lib.sqlite3_open_v2(bdata.db, ctypes.byref(db_ptr), 6, None) # 6 READWRITE|CREATE if rc ! 0: print(Open failed:, rc) else: print(DB opened with static lib) sqlite_lib.sqlite3_close(db_ptr)注意ctypes要求显式声明argtypes和restype否则参数传递错位会导致崩溃字符串必须用bxxx字节串6是SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE的整数值查sqlite3.h可得。此方式完全脱离pysqlite3你的 Python 环境甚至可以没有sqlite3模块。4. 避坑指南五个血泪经验换来的常见问题排查清单4.1 现象./sqlite3: No such file or directory即使文件存在且有执行权限原因这是 Linux 内核的execve错误根本不是文件不存在而是ELF 解释器interpreter路径无效。readelf -l ./sqlite3 | grep interpreter显示/lib64/ld-linux-x86-64.so.2glibc或/lib/ld-musl-x86_64.so.1musl。若目标系统没有该解释器如某些极简 initramfs就会报此错。解决确认Sqlite3-static.7z是 musl 编译版readelf -l ./sqlite3 | grep interpreter应输出ld-musl。若误用 glibc static 版立即更换。musl 解释器在几乎所有 Linux 发行版的/lib/下都存在。4.2 现象sqlite3: error while loading shared libraries: libsqlite3.so.0: cannot open shared object file原因你执行的是动态版sqlite3不是 static 版。常见于解压后没加bin/到PATH却误用了系统/usr/bin/sqlite3或which sqlite3显示/usr/bin/sqlite3但你以为是刚解压的。解决执行which sqlite3和ls -la $(which sqlite3)确认路径指向sqlite3-static/bin/sqlite3用绝对路径/path/to/sqlite3-static/bin/sqlite3 --version强制验证。4.3 现象fts5扩展不可用CREATE VIRTUAL TABLE t USING fts5(x)报no such module: fts5原因Sqlite3-static.7z的构建配置中未定义SQLITE_ENABLE_FTS5宏或你下载的是旧版本3.30.0。解决检查sqlite3 --version输出的完整版本号如3.45.1 2024-03-12...确认 ≥3.30.0执行sqlite3 -cmd PRAGMA compile_options;输出中必须包含ENABLE_FTS5。若无说明该包未启用需重新下载或自行编译。4.4 现象C 程序链接时报undefined reference to sqlite3_open_v2原因链接顺序错误。GCC 要求-lxxx必须放在源文件之后。gcc logger.c -lsqlite3会失败gcc -lsqlite3 logger.c也会失败正确是gcc logger.c -lsqlite3。解决严格遵守gcc [源文件] [选项] -l[库名]顺序或用pkg-config若提供.pc文件gcc logger.c $(pkg-config --cflags --libs sqlite3-static)。4.5 现象Python ctypes 加载libsqlite3.so后调用sqlite3_open_v2返回21SQLITE_MISUSE原因ctypes.CDLL()加载后未正确设置函数参数类型argtypes导致 C 函数收到垃圾指针。解决必须为每个调用的函数设置argtypes和restype参考 3.4 节代码。漏掉任一函数都会导致未定义行为。5. 进阶技巧用sqlite3-static构建可验证的离线数据管道附自动化校验脚本5.1 为什么离线环境需要“可验证”在工控、航天、医疗设备等场景交付物不能只说“能跑”必须提供可审计、可回放、可对比的验证证据。比如客户拿到data.db和sqlite3-static如何证明这个 DB 确实是用fts5创建的、没有被篡改、且查询结果与开发环境一致答案是把验证逻辑也打包进 static 生态。5.2 构建一个自验证的.sql脚本包设想你要交付一个“设备日志分析包”包含analyzer.sql含CREATE VIRTUAL TABLE log_fts USING fts5(msg);和SELECT * FROM log_fts WHERE msg MATCH error;sqlite3-static/bin/sqlite3确保fts5可用verify.sh自动执行并比对哈希verify.sh内容如下纯 Bash无外部依赖#!/bin/sh # verify.sh —— 离线可执行的验证脚本 set -e # 任何命令失败即退出 SQLITE./sqlite3-static/bin/sqlite3 DBdata.db SQL_SCRIPTanalyzer.sql # 步骤1检查 sqlite3 是否为 musl static 版 if ! $SQLITE --version /dev/null 21; then echo ERROR: sqlite3 not found or not executable exit 1 fi if ! $SQLITE -cmd PRAGMA compile_options; 2/dev/null | grep -q ENABLE_FTS5; then echo ERROR: fts5 extension not enabled in sqlite3 exit 1 fi # 步骤2执行 SQL 脚本捕获输出并生成 SHA256 OUTPUT_FILEoutput.txt $SQLITE $DB $SQL_SCRIPT $OUTPUT_FILE 2/dev/null RESULT_HASH$(sha256sum $OUTPUT_FILE | cut -d -f1) # 步骤3与预存的黄金哈希比对此哈希由开发环境生成并写入 verify.sh GOLDEN_HASHa1b2c3d4e5f6...32字节 if [ $RESULT_HASH $GOLDEN_HASH ]; then echo ✅ Verification PASSED: Output matches expected hash echo Hash: $RESULT_HASH else echo ❌ Verification FAILED! echo Expected: $GOLDEN_HASH echo Got: $RESULT_HASH echo Full output saved to $OUTPUT_FILE for inspection exit 1 fi关键设计set -e确保任意步骤失败立即终止$SQLITE -cmd PRAGMA compile_options;是检测扩展的最轻量方法sha256sum是 BusyBox 和所有主流 Linux 都自带的命令无需额外安装黄金哈希写死在脚本里交付时即固化不可篡改。5.3 自动化生成黄金哈希的工作流开发侧在你的开发机上用同一份sqlite3-static和analyzer.sql执行# 1. 确保用的是 static 版 export PATH/path/to/sqlite3-static/bin:$PATH # 2. 生成标准输出 sqlite3 data.db analyzer.sql output_ref.txt # 3. 计算哈希 sha256sum output_ref.txt | cut -d -f1 # 复制此结果 # 4. 粘贴到 verify.sh 的 GOLDEN_HASH 变量中这样交付包里的verify.sh就成了“数字指纹”——客户双击运行要么绿 ✅要么红 ❌没有任何解释空间。这比写一百页《部署手册》都管用。5.4 一个真实教训从那以后我每次交付 SQLite 相关包都强制走一遍verify.sh流程去年在某工业网关项目我们交付了sqlite3-static和一个init.sql客户反馈“查询很慢”。排查三天发现是客户自己用系统sqlite33.7.17执行了init.sql而fts5在 3.9.0 才引入CREATE VIRTUAL TABLE ... USING fts5语句被静默忽略表实际是普通表MATCH查询退化为全表扫描。如果我们当时提供了verify.sh并要求客户首验这个问题会在 5 分钟内暴露。从那以后我每次交付 SQLite 相关包都强制走一遍verify.sh流程——不是为了防客户而是防自己疏忽。把验证变成交付物的一部分而不是口头承诺这才是工程师对确定性的基本尊重。希望帮到你。本文还有配套的精品资源点击获取
企业数字化 ERP 产品动态
相关推荐
OpenAI和Google定制声音方案对比与选型指南 最近我在做一款AI语音产品,需要给不同角色定制专属音色,对比了一圈方案,发现OpenAI和Google在“定制声音”这件事上的产品思路完全是两个极端:OpenAI的Custom Voice需要提交申请、联系销售、走商务流程,而Google这边直… · 2026/11/4 17:55:14
3.3万Star开源声音克隆项目:本地部署与微调实战全解析 凌晨刷 GitHub 的时候,我看到 Star 数停在 3.3 万这个数字上,第一反应是:又一个声音克隆项目起来了。说真的,这两年 AI 圈每隔几个月就会冒出一个叫好又叫座的语音项目,但大多数火几天热度就下去了。能冲到 3.3 万 Sta… · 2026/11/4 17:55:13
Git与CICD实战:从代码管理到自动化部署 1. 项目部署流程解析 在软件开发领域,从代码编写到最终上线运行需要经历一系列标准化的流程。以陌陌APP为例,我们来看一个典型的项目部署生命周期:
1.1 源代码获取与管理 现代软件开发中,代码仓库是团队协作的核心枢纽。常见的代… · 2026/11/4 17:55:13
WaferMap格式转换工具:免费解决晶圆图数据格式混乱 芯片良率分析这个圈子里,WaferMap 数据的格式混乱是个老生常谈的痛点。不同测试机台、不同封装厂、不同 EDA 工具导出的晶圆图文件,格式五花八门,有的用纯文本坐标列表,有的用带表头的 CSV,有的干脆是二进制加自定义头… · 2026/11/5 3:00:06
STM32自平衡小车入门:从单轮驱动到PID平衡控制实战 简介:这份资料包面向嵌入式初学者与DIY爱好者,围绕基于STM32微控制器的两轮自平衡小车展开,从硬件原理到软件实现提供了一套可落地的制作参考。包内共1430个文件,以c与h源码、d与o编译中间文件、crf与dep工程索引为主,… · 2026/11/5 3:00:06
STM32自平衡小车入门实战:从零搭建到闭环控制 简介:这份资料包面向嵌入式初学者与DIY爱好者,围绕基于STM32微控制器的两轮自平衡小车展开,提供从硬件设计到软件实现的完整制作参考。包内共1430个文件,以c与h源码、d与o编译中间文件、crf与dep工程索引为主,辅以pdf原… · 2026/11/5 3:00:06
LSTM与Adaboost集成的时间序列预测实战 1. 项目背景与核心价值这个标题看起来复杂,但拆解后其实包含了一套非常实用的时间序列预测解决方案。我在电力负荷预测项目中实际应用过类似组合,效果比单一LSTM提升约23%。核心思路是通过集成学习弥补单一模型的局限性,再用核密度估计量化预… · 2026/11/5 3:00:06
舞蹈课程预约小程序开发与优化实践 1. 项目概述:舞蹈课程预约小程序的核心价值舞蹈培训机构的管理者经常面临这样的困扰:前台电话被打爆、课程预约混乱、学员到场率难以统计。这套微信小程序解决方案正是为解决这些痛点而生。作为一款专为舞蹈工作室设计的约课工具,它实现了从课… · 2026/11/5 3:00:06
反编译源码还原实战:从体检到编译的完整指南 简介:这份资源是经过反编译还原的倾城项目完整源码,面向希望研究客户端与服务器端实现逻辑的开发者、逆向工程学习者及安全审计人员,可用于理解网络通信、协议交互与系统架构设计。压缩包共581个文件,以539个java源文件为主体&… · 2026/11/5 2:59:06
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 3:16:49
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 6:59:29
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 7:02:38
多智能体协作系统架构设计与实践优化 1. 多智能体协作系统的时代背景2017年Transformer架构的诞生彻底改变了人工智能的发展轨迹。当行业还沉浸在单一大模型带来的性能突破时,Anthropic的研究团队已经将目光投向了更前沿的领域——如何让多个智能体通过协作产生超越单体能力的系统智能。这就像交响乐团中… · 2026/11/5 0:00:39
大模型系统性入门实战指南:从原理到部署微调的全链路路线 提到大模型的系统性入门,我先说个结论:这事真不难,难的是资料太散、路线太多,今天这个框架明天那个工具,新人很容易在“收藏夹吃灰”和“教程看到一半放弃”之间反复横跳。市面上关于大模型的内容少说有几十万篇&#… · 2026/11/5 0:00:39
鸿蒙文件系统沙箱机制解析与开发实践 1. 鸿蒙文件系统沙箱机制深度解析作为一名从Android转向鸿蒙开发的工程师,我深刻体会到文件系统访问是迁移过程中最先遇到的"拦路虎"。在Android上运行良好的文件读写代码,在鸿蒙真机环境却频频出现文件写入后神秘消失或直接抛出权限拒绝错误的… · 2026/11/5 0:00:39
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 3:16:49
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 6:59:29
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 7:02:38