<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>DuckBurnIncense&apos;s Blog</title><description>Lazy Duck</description><link>https://blog.duckburnincense.com/</link><language>zh_CN</language><item><title>在 KDE Dolphin 的右键菜单中增加选项</title><link>https://blog.duckburnincense.com/posts/add-option-to-kde-dolphin-context-menu/</link><guid isPermaLink="true">https://blog.duckburnincense.com/posts/add-option-to-kde-dolphin-context-menu/</guid><description>在 KDE Dolphin 右键菜单 (上下文菜单 / Context Menu) 中增加 &quot;在此处打开 VC Code&quot; 选项</description><pubDate>Mon, 30 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;每次想在指定目录下打开 VS Code 都得用 Open Terminal Here 选项开一个终端, 再敲 &lt;code&gt;code .&lt;/code&gt; 来在当前目录下打开 VS Code, 实在是太不方便了. 有没有方法直接往右键菜单塞东西呢?&lt;/p&gt;
&lt;p&gt;有的兄弟有的, 根据 &lt;a href=&quot;https://develop.kde.org/docs/apps/dolphin/service-menus/&quot;&gt;KDE Dolphin 文档&lt;/a&gt;, 我们可以往 &lt;code&gt;~/.local/share/kservices5/ServiceMenus/&lt;/code&gt; 里面塞一个 &lt;code&gt;desktop&lt;/code&gt; 文件, 按照文档中说明的格式写好后, 就能在右键菜单里新增一个选项了.&lt;/p&gt;
&lt;p&gt;以下是教程:&lt;/p&gt;
&lt;p&gt;(下面的方法仅在 &lt;code&gt;Dolphin Version 23.08.5&lt;/code&gt;, &lt;code&gt;KDE Plasma Version 5.27.12&lt;/code&gt; 测试过, 不保证通用性)&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;如果文件夹不存在 (默认不存在), 创建一下&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;$ mkdir -p ~/.local/share/kservices5/ServiceMenus/
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;新增一个 &lt;code&gt;desktop&lt;/code&gt; 文件, 这里我就叫 &lt;code&gt;open_in_vscode.desktop&lt;/code&gt; 了&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;$ vim ~/.local/share/kservices5/ServiceMenus/open_in_vscode.desktop
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;写入下列内容&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;[Desktop Entry]
Type=Service
ServiceTypes=KonqPopupMenu/Plugin
MimeType=inode/directory;
Actions=openinvscode
X-KDE-Priority=TopLevel

[Desktop Action openinvscode]
Name=Open in VS Code
Icon=code
Exec=code &quot;%u&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;完成, 就是这么简单, 现在在 Dolphin 里右键, 应该能看到一个叫做 &lt;code&gt;Open in VS Code&lt;/code&gt; 的选项:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./open-in-vscode-has-been-added.png&quot; alt=&quot;Open in VS Code 选项已被添加&quot; /&gt;&lt;/p&gt;
&lt;p&gt;如果没看到的话, 可以在 Dolphin 设置里修改:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./open-dolphin-setting.png&quot; alt=&quot;打开 Dolphin 设置&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./check-the-option-in-dolphin-setting.png&quot; alt=&quot;勾选 Open in VS Code 选项&quot; /&gt;&lt;/p&gt;
&lt;p&gt;终于不用再敲 &lt;code&gt;code .&lt;/code&gt; 了~&lt;/p&gt;
</content:encoded></item><item><title>离线迁移 Ollama 中的特定模型：导出为解压即可使用的 tar.gz 文件</title><link>https://blog.duckburnincense.com/posts/ollama-model-export/</link><guid isPermaLink="true">https://blog.duckburnincense.com/posts/ollama-model-export/</guid><description>通过分析 Ollama 模型的 manifest 与 blobs 依赖关系, 实现单模型的精确导出, 并提供一键打包模型为 .tar.gz 供迁移的自动化脚本.</description><pubDate>Mon, 19 Jan 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;我们经常希望在断网情况下迁移 Ollama 的模型文件, 网上能找到的方法通常都是直接复制粘贴整个 &lt;code&gt;OLLAMA_MODELS&lt;/code&gt; 文件夹, 这固然可以, 但是会迁移 Ollama 里的所有模型. 当我们仅希望迁移其中某一个模型时, 这个方法就非常的不友好了, 一是文件过大, 过多, 迁移过程非常缓慢; 二是里面有很多我们并不需要的模型, 在迁移过后我们还得把他们删掉, 且若目标磁盘空间不足以容纳所有模型, 还会导致迁移失败.&lt;/p&gt;
&lt;p&gt;进一步地, 网上就出现了通过 &lt;code&gt;ollama show --modelfile&lt;/code&gt; 查询模型文件位置, 再迁移修改时间相近的文件的方法, 但此方法仍存在问题: 当多个模型同时依赖一个文件时, 就会导致新的模型依赖旧的文件, 此时再根据修改时间判断, 就会导致迁移不完全.&lt;/p&gt;
&lt;p&gt;那么, Ollama 是怎么判断需要哪些文件的呢?&lt;/p&gt;
&lt;h2&gt;技术论证 &amp;amp; 手动传输示例&lt;/h2&gt;
&lt;p&gt;通过查阅 &lt;a href=&quot;https://github.com/ollama/ollama/blob/main/server/modelpath.go&quot;&gt;Ollama 源代码&lt;/a&gt;可知, Ollama 将模型分别存储在 OLLAMA_MODELS 下的 &lt;code&gt;blobs&lt;/code&gt; 和 &lt;code&gt;manifests&lt;/code&gt; 下, 其中 &lt;code&gt;manifests&lt;/code&gt; 下按照 &lt;code&gt;registry/namespace/repo/tag&lt;/code&gt; 存储模型的 manifest; &lt;code&gt;blobs&lt;/code&gt; 下存储模型 layer 的二进制文件.&lt;/p&gt;
&lt;p&gt;以迁移 &lt;code&gt;deepseek-r1:8b&lt;/code&gt; 为例&lt;/p&gt;
&lt;p&gt;让我们看看它的 manifest 里写了啥:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ sudo cat $OLLAMA_MODELS/manifests/registry.ollama.ai/library/deepseek-r1/8b | jq
{
  &quot;schemaVersion&quot;: 2,
  &quot;mediaType&quot;: &quot;application/vnd.docker.distribution.manifest.v2+json&quot;,
  &quot;config&quot;: {
    &quot;mediaType&quot;: &quot;application/vnd.docker.container.image.v1+json&quot;,
    &quot;digest&quot;: &quot;sha256:f64cd5418e4b038ef90cf5fab6eb7ce6ae8f18909416822751d3b9fca827c2ab&quot;,
    &quot;size&quot;: 487
  },
  &quot;layers&quot;: [
    {
      &quot;mediaType&quot;: &quot;application/vnd.ollama.image.model&quot;,
      &quot;digest&quot;: &quot;sha256:e6a7edc1a4d7d9b2de136a221a57336b76316cfe53a252aeba814496c5ae439d&quot;,
      &quot;size&quot;: 5225373760
    },
    {
      &quot;mediaType&quot;: &quot;application/vnd.ollama.image.template&quot;,
      &quot;digest&quot;: &quot;sha256:c5ad996bda6eed4df6e3b605a9869647624851ac248209d22fd5e2c0cc1121d3&quot;,
      &quot;size&quot;: 556
    },
    {
      &quot;mediaType&quot;: &quot;application/vnd.ollama.image.license&quot;,
      &quot;digest&quot;: &quot;sha256:6e4c38e1172f42fdbff13edf9a7a017679fb82b0fde415a3e8b3c31c6ed4a4e4&quot;,
      &quot;size&quot;: 1065
    },
    {
      &quot;mediaType&quot;: &quot;application/vnd.ollama.image.params&quot;,
      &quot;digest&quot;: &quot;sha256:ed8474dc73db8ca0d85c1958c91c3a444e13a469c2efb10cd777ca9baeaddcb7&quot;,
      &quot;size&quot;: 179
    }
  ]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;不难发现, JSON 中各&lt;code&gt;digest&lt;/code&gt; 对应 &lt;code&gt;$OLLAMA_MODELS/blobs&lt;/code&gt; 下各 &lt;code&gt;sha256-&lt;/code&gt; 开头的文件. 不过其中 &lt;code&gt;config.digest&lt;/code&gt; 最为可疑, 单独一个字段存着, 让我们看看里面是啥:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ sudo cat /usr/share/ollama/.ollama/models/blobs/sha256-f64cd5418e4b038ef90cf5fab6eb7ce6ae8f18909416822751d3b9fca827c2ab | jq
{
  &quot;model_format&quot;: &quot;gguf&quot;,
  &quot;model_family&quot;: &quot;qwen3&quot;,
  &quot;model_families&quot;: [
    &quot;qwen3&quot;
  ],
  &quot;model_type&quot;: &quot;8.2B&quot;,
  &quot;file_type&quot;: &quot;Q4_K_M&quot;,
  &quot;architecture&quot;: &quot;amd64&quot;,
  &quot;os&quot;: &quot;linux&quot;,
  &quot;rootfs&quot;: {
    &quot;type&quot;: &quot;layers&quot;,
    &quot;diff_ids&quot;: [
      &quot;sha256:e6a7edc1a4d7d9b2de136a221a57336b76316cfe53a252aeba814496c5ae439d&quot;,
      &quot;sha256:c5ad996bda6eed4df6e3b605a9869647624851ac248209d22fd5e2c0cc1121d3&quot;,
      &quot;sha256:6e4c38e1172f42fdbff13edf9a7a017679fb82b0fde415a3e8b3c31c6ed4a4e4&quot;,
      &quot;sha256:ed8474dc73db8ca0d85c1958c91c3a444e13a469c2efb10cd777ca9baeaddcb7&quot;
    ]
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;看起来像是描述模型用的, 且下面的 &lt;code&gt;rootfs.diff_ids&lt;/code&gt; 内容与 &lt;code&gt;layers[].digest&lt;/code&gt; 完全一致, 不需要额外处理.&lt;/p&gt;
&lt;p&gt;那就好办了, 在当前 Ollama 的实现下, 只需要把 manifest 里有的 digest 全部迁移, 就能跑了:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;scp $OLLAMA_MODELS/blobs/sha256-f64cd5418e4b038ef90cf5fab6eb7ce6ae8f18909416822751d3b9fca827c2ab root@another-server:/path/to/OLLAMA_MODELS/blobs/
scp $OLLAMA_MODELS/blobs/sha256-e6a7edc1a4d7d9b2de136a221a57336b76316cfe53a252aeba814496c5ae439d root@another-server:/path/to/OLLAMA_MODELS/blobs/
scp $OLLAMA_MODELS/blobs/sha256-c5ad996bda6eed4df6e3b605a9869647624851ac248209d22fd5e2c0cc1121d3 root@another-server:/path/to/OLLAMA_MODELS/blobs/
scp $OLLAMA_MODELS/blobs/sha256-6e4c38e1172f42fdbff13edf9a7a017679fb82b0fde415a3e8b3c31c6ed4a4e4 root@another-server:/path/to/OLLAMA_MODELS/blobs/
scp $OLLAMA_MODELS/blobs/sha256-ed8474dc73db8ca0d85c1958c91c3a444e13a469c2efb10cd777ca9baeaddcb7 root@another-server:/path/to/OLLAMA_MODELS/blobs/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;别忘了还有 manifest 本身:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;scp $OLLAMA_MODELS/manifests/registry.ollama.ai/library/deepseek-r1/8b root@another-server:/path/to/OLLAMA_MODELS/manifests/registry.ollama.ai/library/deepseek-r1/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;接下来到目标服务器&lt;/p&gt;
&lt;p&gt;确认一下传输是否成功:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ ollama pull deepseek-r1:8b
pulling manifest 
pulling e6a7edc1a4d7: 100% ▕█████████████████████████████████▏ 5.2 GB                         
pulling c5ad996bda6e: 100% ▕█████████████████████████████████▏  556 B                         
pulling 6e4c38e1172f: 100% ▕█████████████████████████████████▏ 1.1 KB                         
pulling ed8474dc73db: 100% ▕█████████████████████████████████▏  179 B                         
pulling f64cd5418e4b: 100% ▕█████████████████████████████████▏  487 B                         
verifying sha256 digest 
writing manifest 
success 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;pull 应该瞬间完成, 虽然 CLI 仍会显示 pulling 进度, 但如果 blobs 已存在, 实际不会发生网络下载.&lt;/p&gt;
&lt;p&gt;看看新模型, 应该已经在列表里了:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ ollama list
NAME                                           ID              SIZE      MODIFIED      
deepseek-r1:8b                                 6995872bfe4c    5.2 GB    6 seconds ago    
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;直接 run, 也能跑得起来, 证明迁移成功:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ ollama run deepseek-r1:8b
&amp;gt;&amp;gt;&amp;gt; Send a message (/? for help)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;但是你要是说: 主播主播, 一个个手动复制粘贴 sha256, 再 scp 还是太吃操作了, 有没有更简便一点的操作?&lt;/p&gt;
&lt;h2&gt;自动传输&lt;/h2&gt;
&lt;p&gt;有的兄弟有的, 我也嫌麻烦, 于是写了个脚本:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;开源仓库链接&lt;/strong&gt;：
👉 &lt;a href=&quot;https://github.com/DuckBurnIncense/ollama-model-exporter.sh&quot;&gt;https://github.com/DuckBurnIncense/ollama-model-exporter.sh&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;这个脚本可以&lt;strong&gt;全自动&lt;/strong&gt;帮你处理好上述过程，给你打包一个&lt;strong&gt;能够直接传过去、解压就能用&lt;/strong&gt;的 &lt;code&gt;tar.gz&lt;/code&gt; 文件。&lt;/p&gt;
&lt;h3&gt;使用方法:&lt;/h3&gt;
&lt;h4&gt;1. 安装依赖&lt;/h4&gt;
&lt;p&gt;脚本依赖以下工具, 请确保已安装:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;bash &amp;gt;= 4&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;curl&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;jq&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;tar&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果不会装, 请看开源仓库的 README&lt;/p&gt;
&lt;h4&gt;2. 下载脚本&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;$ curl -O https://raw.githubusercontent.com/DuckBurnIncense/ollama-model-exporter.sh/refs/heads/master/ollama-model-exporter.sh
$ chmod +x ollama-model-exporter.sh
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;3. 导出模型为 tar.gz&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;sudo ./ollama-model-exporter.sh deepseek-r1:8b ./deepseek-r1-8b.tar.gz
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;执行完成后, 会生成一个结构&lt;strong&gt;完全符合 Ollama 官方目录布局&lt;/strong&gt;的压缩包.&lt;/p&gt;
&lt;p&gt;如果你只是想看看脚本会打包哪些文件，可以使用 dry-run：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo ./ollama-model-exporter.sh --dry-run deepseek-r1:8b ./deepseek-r1-8b.tar.gz
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;4. 在目标服务器恢复模型&lt;/h4&gt;
&lt;p&gt;在目标服务器上, 确认 &lt;code&gt;OLLAMA_MODELS&lt;/code&gt; 目录 (通常是下面两个之一):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/usr/share/ollama/.ollama/models
~/.ollama/models
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果不是, 那就自行确认吧, 一般在 ollama.service 文件的环境变量里会写&lt;/p&gt;
&lt;p&gt;然后直接解压:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;tar -xzf ./deepseek-r1-8b.tar.gz -C /usr/share/ollama/.ollama/models
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;注意: &lt;strong&gt;一定要解压到 &lt;code&gt;OLLAMA_MODELS&lt;/code&gt; 目录本身, 而不是它的父目录!&lt;/strong&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h4&gt;5. 验证模型是否可用&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;ollama pull deepseek-r1:8b
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果 blobs 已存在, 这一步会非常快, 主要是校验 manifest.&lt;/p&gt;
&lt;p&gt;然后:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ollama list
ollama run deepseek-r1:8b
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;能正常跑起来, 就说明迁移成功&lt;/p&gt;
&lt;h4&gt;核心原理&lt;/h4&gt;
&lt;p&gt;这个脚本的核心思路其实非常简单, 本质就是&lt;strong&gt;把 Ollama 自己 &quot;认为是一个模型的最小集合&quot; 精确地打包出来&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;总结下来就是 5 步:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;调用 Ollama HTTP API&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;http://localhost:11434/api/show
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;判断模型是否存在, 并获取 &lt;code&gt;modelfile&lt;/code&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;从 modelfile 中解析 &lt;code&gt;FROM /path/to/blobs/sha256-*&lt;/code&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;由此反推出 &lt;code&gt;OLLAMA_MODELS&lt;/code&gt; 根目录&lt;/li&gt;
&lt;li&gt;不依赖硬编码路径, 适配系统安装与用户安装&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;定位模型 manifest&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;manifests/registry.ollama.ai/&amp;lt;namespace&amp;gt;/&amp;lt;repo&amp;gt;/&amp;lt;tag&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;解析 manifest&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;读取 &lt;code&gt;config.digest&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;读取 &lt;code&gt;layers[].digest&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;得到模型真正依赖的全部 &lt;code&gt;sha256&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;只打包必要文件&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;manifests/.../&amp;lt;tag&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;blobs/sha256-*&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;使用 &lt;code&gt;tar -C &quot;$OLLAMA_MODELS&quot;&lt;/code&gt; 压缩所有需要的文件&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;最终得到的 &lt;code&gt;tar.gz&lt;/code&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;不多&lt;/li&gt;
&lt;li&gt;不少&lt;/li&gt;
&lt;li&gt;不包含无关模型&lt;/li&gt;
&lt;li&gt;不依赖修改时间&lt;/li&gt;
&lt;li&gt;可直接解压复用&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;总结&lt;/h2&gt;
&lt;p&gt;如果你只是想&lt;strong&gt;整机备份&lt;/strong&gt;, 直接复制整个 &lt;code&gt;OLLAMA_MODELS&lt;/code&gt; 当然没问题;
但如果你像我一样, 只想&lt;strong&gt;精确迁移某一个模型&lt;/strong&gt;, 尤其是在:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;离线环境&lt;/li&gt;
&lt;li&gt;带宽有限, 重新 pull 很慢&lt;/li&gt;
&lt;li&gt;模型很多&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;的情况下，这种基于 &lt;strong&gt;manifest 精确依赖分析&lt;/strong&gt; 的方式, 会靠谱得多&lt;/p&gt;
&lt;p&gt;希望这篇文章能帮你少浪费点时间&lt;/p&gt;
&lt;p&gt;(脚本有问题欢迎提 Issue, (我应该没写 bug 吧...?))&lt;/p&gt;
</content:encoded></item><item><title>分析并解决新安全限制导致 Ubuntu 24.04 下运行 electron 的 AppImage 报错 The SUID sandbox helper binary was found, but is not configured correctly</title><link>https://blog.duckburnincense.com/posts/ubuntu-24-04-unprivileged-user-namespace-suid-sandbox-error-electron-appimage/</link><guid isPermaLink="true">https://blog.duckburnincense.com/posts/ubuntu-24-04-unprivileged-user-namespace-suid-sandbox-error-electron-appimage/</guid><description>报错类似 The SUID sandbox helper binary was found, but is not configured correctly. Rather than run without sandboxing I&apos;m aborting now. You need to make sure that /tmp/.mount_LyuKLU/chrome-sandbox is owned by root and has mode 4755.</description><pubDate>Wed, 07 Jan 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;复现方法&lt;/h2&gt;
&lt;p&gt;使用如下命令, 运行我刚构建好的 electron 程序:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ chmod +x ./my-electron-app.AppImage
$ ./my-electron-app.AppImage
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;报错如下&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[26568:0107/005131.867292:FATAL:sandbox/linux/suid/client/setuid_sandbox_host.cc:166] The SUID sandbox helper binary was found, but is not configured correctly. Rather than run without sandboxing I&apos;m aborting now. You need to make sure that /tmp/.mount_LyuKLU/chrome-sandbox is owned by root and has mode 4755.
Trace/breakpoint trap (core dumped)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;按照提示, 最佳的解决方案应该是:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ sudo chown root:root /tmp/.mount_LyuKLU/chrome-sandbox
$ sudo chmod 4755 /tmp/.mount_LyuKLU/chrome-sandbox
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然而, 显然 &lt;code&gt;/tmp/.mount_LyuKLU&lt;/code&gt; 是一个临时目录, 在程序运行结束后就被销毁掉了, 我们无法卡时机, 在文件被创建后, 被执行前修改其权限, 因此需要一些变通方案.&lt;/p&gt;
&lt;h3&gt;报错原因&lt;/h3&gt;
&lt;p&gt;通过查询资料, 得知这是 Ubuntu 24.04 为了增加安全性所改进的限制, 在 Ubuntu 24.04 发行说明中有提及: &lt;a href=&quot;https://discourse.ubuntu.com/t/ubuntu-24-04-lts-noble-numbat-release-notes/39890#p-99950-unprivileged-user-namespace-restrictions&quot;&gt;Unprivileged user namespace restrictions&lt;/a&gt;. 文中提到: Ubuntu 内核现在限制了无特权用户命名空间的使用, 这影响系统上所有无特权和未限制的程序.&lt;/p&gt;
&lt;h3&gt;解决方案&lt;/h3&gt;
&lt;p&gt;对于此类问题, 解决方案基本有四种:&lt;/p&gt;
&lt;h4&gt;修复文件权限 (不适用上文场景)&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;$ sudo chown root:root /path/to/chrome-sandbox
$ sudo chmod 4755 /path/to/chrome-sandbox
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;使用 AppArmor 配置 (不适用上文场景)&lt;/h4&gt;
&lt;p&gt;根据&lt;a href=&quot;https://discourse.ubuntu.com/t/ubuntu-24-04-lts-noble-numbat-release-notes/39890#p-99950-unprivileged-user-namespace-restrictions&quot;&gt;Ubuntu 24.04 发行说明&lt;/a&gt;与 &lt;a href=&quot;https://ubuntu.com/server/docs/security-apparmor&quot;&gt;AppArmor 文档&lt;/a&gt;,&lt;/p&gt;
&lt;p&gt;AppArmor 新增了一个 unconfined 配置模式 / 标志, 该模式将配置指定为基本上像 AppArmor 的无限制模式, 其中应用程序不受限制, 并允许添加额外的权限, 例如 &lt;code&gt;userns,&lt;/code&gt; 权限.&lt;/p&gt;
&lt;p&gt;例如: 对于 chrome, 编辑 &lt;code&gt;/etc/apparmor.d/chrome&lt;/code&gt; 配置文件如下:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;abi &amp;lt;abi/4.0&amp;gt;,

include &amp;lt;tunables/global&amp;gt;

/opt/google/chrome/chrome flags=(unconfined) {
  userns,

  # Site-specific additions and overrides. See local/README for details.
  include if exists &amp;lt;local/chrome&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;使用 &lt;code&gt;--no-sandbox&lt;/code&gt; 选项&lt;/h4&gt;
&lt;p&gt;最方便, 但不建议&lt;/p&gt;
&lt;p&gt;直接使用 &lt;code&gt;--no-sandbox&lt;/code&gt; 选项运行 AppImage:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ ./my-electron-app.AppImage --no-sandbox
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;关闭安全限制&lt;/h4&gt;
&lt;p&gt;关闭后, 会存在无特权用户命名空间功能的内核漏洞, 不建议&lt;/p&gt;
&lt;p&gt;临时关闭:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;永久关闭:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ echo &quot;kernel.apparmor_restrict_unprivileged_userns=0&quot; | sudo tee /etc/sysctl.d/60-apparmor-namespace.conf
$ sudo sysctl -p /etc/sysctl.d/60-apparmor-namespace.conf
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;p&gt;参考资料:&lt;/p&gt;
&lt;p&gt;https://discourse.ubuntu.com/t/ubuntu-24-04-lts-noble-numbat-release-notes/39890#p-99950-unprivileged-user-namespace-restrictions&lt;/p&gt;
&lt;p&gt;https://github.com/electron/electron/issues/42510#issuecomment-2171583086&lt;/p&gt;
&lt;p&gt;https://github.com/arduino/arduino-ide/issues/2429#issuecomment-2099775010&lt;/p&gt;
</content:encoded></item><item><title>必应搜索引擎收录使用 DNS CNAME 验证子域名一直无法检测到 CNAME 记录的解决方案</title><link>https://blog.duckburnincense.com/posts/bing-webmaster-cname-verify-failure/</link><guid isPermaLink="true">https://blog.duckburnincense.com/posts/bing-webmaster-cname-verify-failure/</guid><description>Bing Webmaster Tools 使用 DNS CNAME 验证子域名一直无法检测到 CNAME 记录的解决方案</description><pubDate>Mon, 08 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;闲着没事想给本站搞个搜索引擎收录, 由于以前有过在 &lt;a href=&quot;https://www.bing.com/webmasters/&quot;&gt;Bing Webmaster Tools&lt;/a&gt; 提交网站的经验, 于是首选了 bing.&lt;/p&gt;
&lt;p&gt;这里因为要收录 &lt;code&gt;blog.duckburnincense.com&lt;/code&gt;, 因此当然是直接填写:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./bing-webmaster-submit.png&quot; alt=&quot;提交网站页面&quot; /&gt;&lt;/p&gt;
&lt;p&gt;然后来到验证页面, 三种验证方式, 因为我这是自动构建的静态网站, 若选择前两种验证方案, 我还得修改网站内容, 重新 push 到 GitHub, 再自动 build 才能用. 因此我选择了向 DNS 中添加 CNAME 记录来验证.&lt;/p&gt;
&lt;p&gt;页面要求向 DNS 中添加一条名为 &lt;code&gt;e6943c76455e2e78a7e06a7d2b4befc6e6943c76455e2e78a7e06a7d2b4befc6&lt;/code&gt; 的, 指向 &lt;code&gt;verify.bing.com&lt;/code&gt; 的 CNAME 记录, 因此, 我理所应当地添加了 DNS 记录:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./cloudflare-dns-wrong.png&quot; alt=&quot;错误的 DNS 记录&quot; /&gt;&lt;/p&gt;
&lt;p&gt;随后等待一段时间, 点击提交验证按钮, 提示未找到 CNAME 记录. 此时我还以为是 DNS 还未传播, 于是随后多次等待, 提交, 均无果:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./bing-webmaster-dns-verify.png&quot; alt=&quot;bing 提示验证失败&quot; /&gt;&lt;/p&gt;
&lt;p&gt;然后我突然想起来, 我加的是 &lt;code&gt;blog.duckburnincense.com&lt;/code&gt; 而不是 &lt;code&gt;duckburnincense.com&lt;/code&gt;, 因此应该向 &lt;code&gt;blog.duckburnincense.com&lt;/code&gt; 添加 CNAME 记录, 因此 DNS 管理器中的 name 中应该填写 &lt;code&gt;e6943c76455e2e78a7e06a7d2b4befc6e6943c76455e2e78a7e06a7d2b4befc6.blog&lt;/code&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./cloudflare-dns-correct.png&quot; alt=&quot;正确的 DNS 配置&quot; /&gt;&lt;/p&gt;
&lt;p&gt;随后再次点击验证按钮, 验证成功.&lt;/p&gt;
</content:encoded></item><item><title>导出 Microsoft Authenticator 中的 2FA 密钥</title><link>https://blog.duckburnincense.com/posts/export-ms-authenticator-2fa-secret-key/</link><guid isPermaLink="true">https://blog.duckburnincense.com/posts/export-ms-authenticator-2fa-secret-key/</guid><description>MS Authenticator 官方似乎并没有提供导出密钥的方法, 不过还好, 我有 root 权限. 通过直接读取其数据库获得密钥</description><pubDate>Wed, 19 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;strong&gt;注意: 此方法需要你具有你的手机的 root 权限&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;我在电脑上一直用浏览器拓展 &lt;a href=&quot;https://github.com/Authenticator-Extension/Authenticator&quot;&gt;&quot;Authenticator&quot;&lt;/a&gt; 来管理 2FA 密钥, 然而前日我在新电脑上登了 Firefox 账号, 并删除了 Firefox 自动同步到新电脑上的 Authenticator 拓展 (因为我觉得我在这个电脑上并不需要 Authenticator), 然而 Firefox 又将 &quot;删除 Authenticator 拓展&quot; 这一行为同步到了旧电脑上, 于是我在电脑上的 2FA 就丢失了...&lt;/p&gt;
&lt;p&gt;好在我手机上的 Microsoft Authenticator 还存在 2FA 的 TOTP 代码, 可是 MS Authenticator 官方似乎并没有提供导出密钥的方法, 不过还好, 我有 root 权限. 于是我们尝试直接读取其数据库获得密钥.&lt;/p&gt;
&lt;h4&gt;第一步: 连上手机, 获得 root shell:&lt;/h4&gt;
&lt;p&gt;在手机 root 管理器中启用 Shell 的 root 权限, 随后 adb 连接到手机:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ adb shell
phone:/ $ su
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;第二步: 找到存储密钥的数据库&lt;/h4&gt;
&lt;p&gt;不难想到, 这么机密的东西, 肯定是存储在应用私有目录下的&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;phone:/ # cd /data/data/com.azure.authenticator/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;可是这么多数据, 哪个里面才存了真实密钥呢?&lt;/p&gt;
&lt;p&gt;不妨将页面上显示的账户名中的 &lt;code&gt;DSM&lt;/code&gt; 作为关键词搜索:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./MS_Auth_DSM_page.jpg&quot; alt=&quot;Microsoft Authenticator 显示账户名和 TOTP 代码的页面&quot; /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;phone:/data/data/com.azure.authenticator # grep -r &quot;DSM&quot; . | head -n 1
Binary file ./databases/PhoneFactor-wal matches
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;找到了 &lt;code&gt;/data/data/com.azure.authenticator/databases/PhoneFactor-wal&lt;/code&gt;, 里面疑似存储着密钥&lt;/p&gt;
&lt;h4&gt;第三步: 打开数据库&lt;/h4&gt;
&lt;p&gt;猜测这是一个数据库文件, 于是试图直接打开该文件, 未果, 那么看看 &lt;code&gt;./databases/&lt;/code&gt; 下还有啥:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;phone:/data/data/com.azure.authenticator # ls ./databases/
AppIdDomainMapping             LabellingData-wal       VerifiableCredential-wallet-db                   experimentation_database           passkey_database_table-wal
AppIdDomainMapping-shm         MfaLibrary              VerifiableCredential-wallet-db-shm               experimentation_database-shm       payment_card_db
AppIdDomainMapping-wal         MfaLibrary-shm          VerifiableCredential-wallet-db-wal               experimentation_database-wal       payment_card_db-shm
AriaStorage.db                 MfaLibrary-wal          app_policy_database                              generator_history_db               payment_card_db-wal
AriaStorage.db-journal         PUDSSchemaDatabase      app_policy_database-shm                          generator_history_db-shm           shared_core_database
EnterpriseDenyListMapping      PUDSSchemaDatabase-shm  app_policy_database-wal                          generator_history_db-wal           shared_core_database-shm
EnterpriseDenyListMapping-shm  PUDSSchemaDatabase-wal  com.google.android.datatransport.events          google_app_measurement.db          shared_core_database-wal
EnterpriseDenyListMapping-wal  PhoneFactor             com.google.android.datatransport.events-journal  google_app_measurement.db-journal
LabellingData                  PhoneFactor-shm         com.microsoft.appcenter.persistence              passkey_database_table
LabellingData-shm              PhoneFactor-wal         com.microsoft.appcenter.persistence-journal      passkey_database_table-shm
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;注意到, 该目录下还有 &lt;code&gt;PhoneFactor&lt;/code&gt; 文件, 并且通过十六进制编辑器查看, 很明显这是一个 Sqlite 3 数据库&lt;/p&gt;
&lt;p&gt;于是&lt;strong&gt;单独&lt;/strong&gt;将 &lt;code&gt;PhoneFactor&lt;/code&gt; 复制到电脑并打开. &lt;code&gt;accounts&lt;/code&gt; 表共有五条记录, 其他 2FA 密钥都在里面, 唯独没有 &quot;DSM&quot; 那条密钥&lt;/p&gt;
&lt;p&gt;猜测其与 &lt;code&gt;PhoneFactor-shm&lt;/code&gt; 和 &lt;code&gt;PhoneFactor-wal&lt;/code&gt; 文件是一对, 需要同时打开. 前往 Sqlite 官网查找&lt;a href=&quot;https://www.sqlite.org/fileformat2.html&quot;&gt;文档&lt;/a&gt;, 确认了猜测:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;4.6. WAL-Index Format
Conceptually, the wal-index is shared memory, though the current VFS implementations use a memory-mapped file for operating-system portability. The memory-mapped file is in the same directory as the database and has the same name as the database with a &quot;-shm&quot; suffix appended. Because the wal-index is shared memory, SQLite does not support journal_mode=WAL on a network filesystem when clients are on different machines, as all clients of the database must be able to share the same memory.
...&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;简而言之&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-wal&lt;/code&gt; 文件‌: 保存未提交的写操作日志, 支持多线程并发写入, 避免传统日志锁定. 当数据库崩溃时, 可通过 WAL 文件恢复未提交的更改.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;‌-shm&lt;/code&gt; 文件: 共享内存文件, 用于协调多线程对 WAL 文件的访问, 确保数据一致性.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;于是将其都复制到电脑上&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ ls
PhoneFactor          PhoneFactor-shm          PhoneFactor-wal
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;打开数据库:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ sqlite3 ./PhoneFactor
SQLite version 3.45.1 2024-01-30 16:01:20
Enter &quot;.help&quot; for usage hints.
sqlite&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;第四步: 提取密钥&lt;/h4&gt;
&lt;p&gt;先来点格式操作: 开启标题行, 改变输出格式&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sqlite&amp;gt; .headers on
sqlite&amp;gt; .mode column
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;看看都有哪些表:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sqlite&amp;gt; .tables
accounts           android_metadata   room_master_table
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;很明显有个 accounts 表, 查看其结构:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sqlite&amp;gt; .schema accounts
CREATE TABLE `accounts` (
  `_id` INTEGER PRIMARY KEY AUTOINCREMENT,
  `group_key` TEXT NOT NULL,
  `name` TEXT NOT NULL,
  `username` TEXT NOT NULL,
  `paws_url` TEXT NOT NULL,
  `oath_secret_key` TEXT NOT NULL,
  `oath_enabled` INTEGER NOT NULL,
  `cid` TEXT NOT NULL,
  `cached_pin` TEXT NOT NULL,
  `ngc_ski` TEXT NOT NULL,
  `aad_user_id` TEXT NOT NULL,
  `aad_tenant_id` TEXT NOT NULL,
  `account_type` INTEGER NOT NULL,
  `account_capability` INTEGER NOT NULL,
  `ux_position` INTEGER NOT NULL,
  `is_totp_code_shown` INTEGER NOT NULL,
  `encrypted_oath_secret_key` TEXT NOT NULL,
  `mfa_pin_encryption_key_alias` TEXT NOT NULL,
  `identity_provider` TEXT NOT NULL,
  `aad_ngc_totp_enabled` INTEGER NOT NULL,
  `aad_authority` TEXT NOT NULL,
  `restore_capability` INTEGER NOT NULL,
  `has_password` INTEGER NOT NULL,
  `aad_security_defaults_policy_enabled` INTEGER NOT NULL,
  `phone_app_detail_id` TEXT NOT NULL,
  `replication_scope` TEXT NOT NULL,
  `activated_device_token` TEXT NOT NULL,
  `routing_hint` TEXT NOT NULL,
  `tenant_country_code` TEXT NOT NULL,
  `data_boundary` TEXT NOT NULL,
  `puid` TEXT NOT NULL
);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;编写 SQL, 查询所有显示名称, 用户名与密钥:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sqlite&amp;gt; SELECT name, username, oath_secret_key FROM accounts;
name             username                                         oath_secret_key                 
---------------  -----------------------------------------------  --------------------------------
Website1         duckburnincense1@duckburnincense.com             QlYxR0o0MTF4N2g3                
Website2         duckburnincense2@duckburnincense.com             QlYxR0o0MTF4N2g3                
Website3         duckburnincense3@duckburnincense.com             QlYxR0o0MTF4N2g3                
Website4         duckburnincense4@duckburnincense.com             QlYxR0o0MTF4N2g3                
Website5         duckburnincense5@duckburnincense.com             QlYxR0o0MTF4N2g3
Synology DSM     duckburnincense6@duckburnincense.com             QlYxR0o0MTF4N2g3
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;oath_secret_key&lt;/code&gt; 列即为 2FA 密钥.&lt;/p&gt;
&lt;p&gt;至此, 折腾结束, 将 &lt;code&gt;oath_secret_key&lt;/code&gt; 逐个导入新的 2FA 管理器即可 (&lt;code&gt;Authenticator&lt;/code&gt; 拓展: 对, 就是我~)&lt;/p&gt;
</content:encoded></item><item><title>在虚拟机中的 Docker 运行 FunASR 时加载模型时一直卡住不动的解决方案</title><link>https://blog.duckburnincense.com/posts/funasr-virtual-machine-docker-model-load-stuck-solution/</link><guid isPermaLink="true">https://blog.duckburnincense.com/posts/funasr-virtual-machine-docker-model-load-stuck-solution/</guid><description>在虚拟机中的 Docker 运行 FunASR 时加载模型时一直卡住不动的解决方案</description><pubDate>Fri, 07 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;在一个 KUbuntu 物理机上测试 &lt;a href=&quot;https://github.com/modelscope/FunASR&quot;&gt;FunASR&lt;/a&gt; 通过后, 在另一台 Windows 电脑的 VMware 中运行了一个全新 KUbuntu 24.04 LTS, 安装 docker 后依据&lt;a href=&quot;https://github.com/modelscope/FunASR/blob/main/runtime/docs/SDK_advanced_guide_online.md&quot;&gt;官方文档&lt;/a&gt;运行, 最后卡在了&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;FunASR  | I20251107 00:52:19.264511    56 funasr-wss-server-2pass.cpp:555] SSL is closed!
FunASR  | I20251107 00:52:19.325332    56 fsmn-vad.cpp:58] Successfully load model from /workspace/models/damo/speech_fsmn_vad_zh-cn-16k-common-onnx/model_quant.onnx
FunASR  | I20251107 00:52:20.740871    56 paraformer.cpp:77] Successfully load model from /workspace/models/damo/speech_paraformer-large_asr_nat-zh-cn-16k-common-vocab8404-online-onnx/model_quant.onnx
FunASR  | I20251107 00:52:21.095985    56 paraformer.cpp:85] Successfully load model from /workspace/models/damo/speech_paraformer-large_asr_nat-zh-cn-16k-common-vocab8404-online-onnx/decoder_quant.onnx
FunASR  | I20251107 00:52:23.210389    56 paraformer.cpp:142] Successfully load model from /workspace/models/damo/speech_paraformer-large-vad-punc_asr_nat-zh-cn-16k-common-vocab8404-onnx/model_quant.onnx
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这里. 通过打开 VMware 的处理器虚拟化, 成功继续往下跑了一行:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;FunASR  | I20251107 00:52:28.818928    56 paraformer.cpp:160] Successfully load lm file /workspace/models/damo/speech_ngram_lm_zh-cn-ai-wesp-fst/TLG.fst
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;随后又卡住了. 通过将虚拟机的内存从 4G 调整到 8G, 成功继续运行下去了:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;FunASR  | I20251107 00:52:29.558418    56 ct-transformer-online.cpp:21] Successfully load model from /workspace/models/damo/punc_ct-transformer_zh-cn-common-vad_realtime-vocab272727-onnx/model_quant.onnx
FunASR  | I20251107 00:52:29.671496    56 itn-processor.cpp:33] Successfully load model from /workspace/models/thuduj12/fst_itn_zh/zh_itn_tagger.fst
FunASR  | I20251107 00:52:29.672539    56 itn-processor.cpp:35] Successfully load model from /workspace/models/thuduj12/fst_itn_zh/zh_itn_verbalizer.fst
FunASR  | I20251107 00:52:29.672549    56 websocket-server-2pass.cpp:596] initAsr run check_and_clean_connection
FunASR  | I20251107 00:52:29.672608    56 websocket-server-2pass.cpp:599] initAsr run check_and_clean_connection finished
FunASR  | I20251107 00:52:29.672616    56 funasr-wss-server-2pass.cpp:571] decoder-thread-num: 12
FunASR  | I20251107 00:52:29.672619    56 funasr-wss-server-2pass.cpp:572] io-thread-num: 1
FunASR  | I20251107 00:52:29.672623    56 funasr-wss-server-2pass.cpp:573] model-thread-num: 1
FunASR  | I20251107 00:52:29.672626    56 funasr-wss-server-2pass.cpp:574] asr model init finished. listen on port:10095
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;因此, 故障原因就是内存不足. 增加虚拟机的内存即可解决.&lt;/p&gt;
&lt;p&gt;GitHub 上有关于此问题的 issue, 但处于 open 状态: &lt;a href=&quot;https://github.com/modelscope/FunASR/issues/2649&quot;&gt;modelscope/FunASR#2649&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;(当时还以为是什么玄学问题, 物理机上能跑起来, 虚拟机里就不行 —— docker 可是以稳定著称的啊, 排查了一下午)&lt;/p&gt;
</content:encoded></item><item><title>Docker import, load, export, save 的区别</title><link>https://blog.duckburnincense.com/posts/docker-import-load-export-save-difference/</link><guid isPermaLink="true">https://blog.duckburnincense.com/posts/docker-import-load-export-save-difference/</guid><description>突击检查, 我知道你知道这些命令不一样, 但是具体哪里不一样?</description><pubDate>Fri, 07 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;我知道你知道这些命令不一样, 但你还记得哪里不一样吗?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;docker import&lt;/code&gt; / &lt;code&gt;docker export&lt;/code&gt;: 导入导出 &lt;strong&gt;container&apos;s filesystem&lt;/strong&gt; (容器的文件系统), 容器文件系统不包括原始镜像的任何元数据或配置信息.
&lt;ul&gt;
&lt;li&gt;例如: &lt;code&gt;docker import /path/to/filesystem.tar your/filesystem&lt;/code&gt;: 导入 &lt;code&gt;/path/to/filesystem.tar&lt;/code&gt; 中的镜像到 docker 的 &lt;code&gt;your/filesystem&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;例如: &lt;code&gt;docker export -o /path/to/filesystem.tar your/filesystem&lt;/code&gt;: 将 docker 中的 &lt;code&gt;your/filesystem&lt;/code&gt; 导出到 &lt;code&gt;/path/to/filesystem.tar&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;docker load&lt;/code&gt; / &lt;code&gt;docker save&lt;/code&gt;: 导入导出 &lt;strong&gt;images&lt;/strong&gt; (镜像)
&lt;ul&gt;
&lt;li&gt;例如: &lt;code&gt;docker load -i /path/to/image.tar&lt;/code&gt;: 导入 &lt;code&gt;/path/to/image.tar&lt;/code&gt; 中的镜像到 docker&lt;/li&gt;
&lt;li&gt;例如: &lt;code&gt;docker save -o /path/to/image.tar your/image:s&lt;/code&gt;: 将 docker 中的 &lt;code&gt;your/image:s&lt;/code&gt; 镜像导出到 &lt;code&gt;/path/to/image.tar&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;下面给出 help&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;docker import --help&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Usage:  docker import [OPTIONS] file|URL|- [REPOSITORY[:TAG]]

Import the contents from a tarball to create a filesystem image

Aliases:
  docker image import, docker import

Options:
  -c, --change list       Apply Dockerfile instruction to the created image
  -m, --message string    Set commit message for imported image
      --platform string   Set platform if server is multi-platform capable
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;docker export --help&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Usage:  docker export [OPTIONS] CONTAINER

Export a container&apos;s filesystem as a tar archive

Aliases:
  docker container export, docker export

Options:
  -o, --output string   Write to a file, instead of STDOUT
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;docker load --help&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Usage:  docker load [OPTIONS]

Load an image from a tar archive or STDIN

Aliases:
  docker image load, docker load

Options:
  -i, --input string   Read from tar archive file, instead of STDIN
  -q, --quiet          Suppress the load output
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;docker save --help&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Usage:  docker save [OPTIONS] IMAGE [IMAGE...]

Save one or more images to a tar archive (streamed to STDOUT by default)

Aliases:
  docker image save, docker save

Options:
  -o, --output string   Write to a file, instead of STDOUT
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;p&gt;我为啥突然要写这个文章? 因为我通过 &lt;code&gt;docker save&lt;/code&gt; 导出了我制作的一个镜像, 然后拿到另一台机器上下意识地通过 &lt;code&gt;docker import&lt;/code&gt; 导入, 然后镜像死活开不起来, 一直报错 &lt;code&gt;error response from daemon no command specified&lt;/code&gt;. 于是我尝试 &lt;code&gt;docker run -it image /bin/bash&lt;/code&gt;, 结果 bash 也没有, 随后试了 &lt;code&gt;sh&lt;/code&gt; 等也不存在, 遂怀疑镜像传输过程中损坏, 但校验 sha256 发现并没有. 折腾了一晚上, 最后 &lt;code&gt;docker inspect image&lt;/code&gt; 发现空荡荡的 (尤其是 entrypoint 也没有, 对应报错中的 &lt;code&gt;no command specified&lt;/code&gt;), 才意识到可能是导入镜像做错了...&lt;/p&gt;
</content:encoded></item><item><title>二次打包 FunASR 官方镜像使其可一键运行</title><link>https://blog.duckburnincense.com/posts/repack-funasr-official-image-one-click-run/</link><guid isPermaLink="true">https://blog.duckburnincense.com/posts/repack-funasr-official-image-one-click-run/</guid><description>官方 FunASR 镜像运行后会进入 bash, 需要再次输入命令才能运行. 二次打包 FunASR 官方镜像, 使其可直接运行, 无需再输命令</description><pubDate>Fri, 07 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;根据&lt;a href=&quot;https://github.com/modelscope/FunASR/blob/main/runtime/docs/SDK_advanced_guide_online.md&quot;&gt;官方文档&lt;/a&gt;, FunASR 启动方式如下:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo docker pull registry.cn-hangzhou.aliyuncs.com/funasr_repo/funasr:funasr-runtime-sdk-online-cpu-0.1.13
mkdir -p ./funasr-runtime-resources/models
sudo docker run -p 10096:10095 -it --privileged=true \
  -v $PWD/funasr-runtime-resources/models:/workspace/models \
  registry.cn-hangzhou.aliyuncs.com/funasr_repo/funasr:funasr-runtime-sdk-online-cpu-0.1.13
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;运行后会进入容器的 bash, 需要再输入下面的命令:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cd FunASR/runtime
nohup bash run_server_2pass.sh \
  --download-model-dir /workspace/models \
  --vad-dir damo/speech_fsmn_vad_zh-cn-16k-common-onnx \
  --model-dir damo/speech_paraformer-large-vad-punc_asr_nat-zh-cn-16k-common-vocab8404-onnx  \
  --online-model-dir damo/speech_paraformer-large_asr_nat-zh-cn-16k-common-vocab8404-online-onnx  \
  --punc-dir damo/punc_ct-transformer_zh-cn-common-vad_realtime-vocab272727-onnx \
  --lm-dir damo/speech_ngram_lm_zh-cn-ai-wesp-fst \
  --itn-dir thuduj12/fst_itn_zh \
  --hotword /workspace/models/hotwords.txt &amp;gt; log.txt 2&amp;gt;&amp;amp;1 &amp;amp;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;才能运行.&lt;/p&gt;
&lt;p&gt;所以, 目标: 使其可通过 &lt;code&gt;docker compose up&lt;/code&gt; 命令一键启动.&lt;/p&gt;
&lt;p&gt;编写 &lt;code&gt;run.sh&lt;/code&gt; 如下, 用于启动服务器:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#!/bin/bash

# 进入工作目录
cd /workspace/FunASR/runtime

# 后台运行服务 (自行调整你需要的参数)
nohup bash run_server_2pass.sh \
  --download-model-dir /workspace/models \
  --vad-dir damo/speech_fsmn_vad_zh-cn-16k-common-onnx \
  --model-dir damo/speech_paraformer-large-vad-punc_asr_nat-zh-cn-16k-common-vocab8404-onnx  \
  --online-model-dir damo/speech_paraformer-large_asr_nat-zh-cn-16k-common-vocab8404-online-onnx  \
  --punc-dir damo/punc_ct-transformer_zh-cn-common-vad_realtime-vocab272727-onnx \
  --lm-dir damo/speech_ngram_lm_zh-cn-ai-wesp-fst \
  --itn-dir thuduj12/fst_itn_zh \
  --hotword /workspace/models/hotwords.txt &amp;gt; log.txt 2&amp;gt;&amp;amp;1 &amp;amp;

# 输出日志
tail -f log.txt
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;编写 &lt;code&gt;Dockerfile&lt;/code&gt; 如下:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 引用基础镜像
FROM registry.cn-hangzhou.aliyuncs.com/funasr_repo/funasr:funasr-runtime-sdk-online-cpu-0.1.13
# 设置时区
ENV TZ=Asia/Shanghai
# 声明端口
EXPOSE 10095/tcp
# 复制刚才创建的用于启动服务器的文件
COPY run.sh /run.sh
# 给予执行权限
RUN chmod +x /run.sh
# 设置入口点
ENTRYPOINT [&quot;/run.sh&quot;]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;构建镜像:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ docker build . -t myfunasr:v1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;编写 &lt;code&gt;docker-compose.yaml&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;services:
  funasr:
    image: myfunasr:v1
    container_name: funasr
    restart: unless-stopped
    # 我也不知道为什么官方文档要 --privileged=true,
    # 我觉得过于不安全, 没加, 但也能跑. 因此加不加取决于你
    privileged: true
    ports:
      - 10096:10095
    volumes:
      - &quot;./funasr-runtime-resources/models:/workspace/models&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;docker compose up -d&lt;/code&gt;, enjoy it~&lt;/p&gt;
&lt;p&gt;参考文章: https://www.cnblogs.com/shizidushu/p/18381237&lt;/p&gt;
</content:encoded></item><item><title>表情包收集</title><link>https://blog.duckburnincense.com/posts/image-macro-collection/</link><guid isPermaLink="true">https://blog.duckburnincense.com/posts/image-macro-collection/</guid><description>不定时更新: 持续收集各种好玩的 (programming 相关) 表情包</description><pubDate>Sat, 04 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;strong&gt;注: 除非注明为原创, 否则本页面所有图片 (表情包) 均由网络收集而来.&lt;/strong&gt; 原创表情包遵循 CC BY 4.0 许可协议.&lt;/p&gt;
&lt;h4&gt;HTTP 5xx 喜报 (原创):&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;./HTTP5xx%E5%96%9C%E6%8A%A5.png&quot; alt=&quot;HTTP 5xx 喜报&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;JS 报错喜报 (原创):&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;./JS%E6%8A%A5%E9%94%99%E5%96%9C%E6%8A%A5.png&quot; alt=&quot;JS 报错喜报&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;Java 喜报:&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;./Java%E5%96%9C%E6%8A%A5.png&quot; alt=&quot;Java 喜报&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;胡言乱语 - USB 插 RJ45 (原创):&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;./%E8%83%A1%E8%A8%80%E4%B9%B1%E8%AF%AD_USB%E6%8F%92RJ45.png&quot; alt=&quot;胡言乱语-USB插RJ45&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;胡言乱语 I2C UART&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;./%E8%83%A1%E8%A8%80%E4%B9%B1%E8%AF%AD_I2C_UART.png&quot; alt=&quot;胡言乱语-I2C-UART&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;牛头不对马嘴 - USB 插 RJ45 (原创):&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;./%E7%89%9B%E5%A4%B4%E4%B8%8D%E5%AF%B9%E9%A9%AC%E5%98%B4-USB%E6%8F%92RJ45.png&quot; alt=&quot;牛头不对马嘴-USB插RJ45&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;前端查数据库&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;./%E5%89%8D%E7%AB%AF%E6%9F%A5%E6%95%B0%E6%8D%AE%E5%BA%93.png&quot; alt=&quot;前端查数据库&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;IQ Boost Pro Max+&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;./IQBoostProMaxPlus.png&quot; alt=&quot;IQBoostProMaxPlus&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;Python: raise&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;./python_raise_vs_throw.png&quot; alt=&quot;Python: raise&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;没日志也没截图, 只能帮你算一卦&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;./%E6%B2%A1%E6%97%A5%E5%BF%97%E6%B2%A1%E6%88%AA%E5%9B%BE%E7%AE%97%E4%B8%80%E5%8D%A6.png&quot; alt=&quot;没日志没截图算一卦&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;PCL 报错提示弹窗&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;./PCL%E6%8A%A5%E9%94%99%E6%8F%90%E7%A4%BA%E5%BC%B9%E7%AA%97.png&quot; alt=&quot;PCL报错提示弹窗&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;提问价格表 1&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;./%E6%8F%90%E9%97%AE%E4%BB%B7%E6%A0%BC%E8%A1%A81.png&quot; alt=&quot;提问价格表&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;提问价格表 2&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;./%E6%8F%90%E9%97%AE%E4%BB%B7%E6%A0%BC%E8%A1%A82.png&quot; alt=&quot;提问价格表2&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;死神微软&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;./%E6%AD%BB%E7%A5%9E%E5%BE%AE%E8%BD%AF.png&quot; alt=&quot;死神微软&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;HyperOS: 不流畅, 巨卡&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;./HyperOS%E4%B8%8D%E6%B5%81%E7%95%85%E5%B7%A8%E5%8D%A1.png&quot; alt=&quot;HyperOS: 不流畅, 巨卡&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;Deepseek: 人类的怪问题怎么那么多&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;./Deepseek%E4%BA%BA%E7%B1%BB%E7%9A%84%E6%80%AA%E9%97%AE%E9%A2%98%E6%80%8E%E4%B9%88%E9%82%A3%E4%B9%88%E5%A4%9A.png&quot; alt=&quot;Deepseek: 人类的怪问题怎么那么多&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;Data Cloud &amp;amp; Serverless&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;./Data_Cloud_and_Serverless.png&quot; alt=&quot;Data Cloud &amp;amp; Serverless&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;Appdata dir&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;./appdata_dir.png&quot; alt=&quot;Appdata dir&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;今天是 520, 我没有配耦&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;./520%E6%B2%A1%E9%85%8D%E8%80%A6.png&quot; alt=&quot;520 没配耦&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;520 过了, 我还是没有配耦&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;./520%E8%BF%87%E4%BA%86%E6%B2%A1%E9%85%8D%E8%80%A6%E5%90%88.png&quot; alt=&quot;520 过了没配耦合&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;买 Mac 打游戏&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;./Mac%E6%89%93%E6%B8%B8%E6%88%8F.png&quot; alt=&quot;Mac打游戏&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;Trump 报纸&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;./Trump%E6%8A%A5%E7%BA%B8.png&quot; alt=&quot;Trump 报纸&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;补湿哥们&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;./%E8%A1%A5%E6%B9%BF%E5%93%A5%E4%BB%AC.png&quot; alt=&quot;补湿哥们&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;不要让学生毕业后成为电子文盲&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;./%E4%B8%8D%E8%A6%81%E8%AE%A9%E5%AD%A6%E7%94%9F%E6%AF%95%E4%B8%9A%E5%90%8E%E6%88%90%E4%B8%BA%E7%94%B5%E5%AD%90%E6%96%87%E7%9B%B2.png&quot; alt=&quot;不要让学生毕业后成为电子文盲&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;sudo rm -rf /* 符&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;./rm-rf%E7%AC%A6.png&quot; alt=&quot;rm-rf符&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;以前的各种接口 vs 现在的各种 Type-C 接口&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;./%E4%BB%A5%E5%89%8D%E7%9A%84%E5%90%84%E7%A7%8D%E6%8E%A5%E5%8F%A3vs%E7%8E%B0%E5%9C%A8%E7%9A%84TypeC%E6%8E%A5%E5%8F%A3.png&quot; alt=&quot;以前的各种接口vs现在的TypeC接口&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;JS 隐式类型转换&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;./JS%E9%9A%90%E5%BC%8F%E7%B1%BB%E5%9E%8B%E8%BD%AC%E6%8D%A2%E4%B8%89%E4%BD%8D%E4%B8%80%E4%BD%93.png&quot; alt=&quot;JS隐式类型转换三位一体&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;Steam 超级管家&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;./Steam%E8%B6%85%E7%BA%A7%E7%AE%A1%E5%AE%B6.png&quot; alt=&quot;Steam超级管家&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;向土豆服务器祈祷&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;./%E5%90%91%E5%9C%9F%E8%B1%86%E6%9C%8D%E5%8A%A1%E5%99%A8%E7%A5%88%E7%A5%B7.png&quot; alt=&quot;向土豆服务器祈祷&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;Choose one&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;./%E9%80%89%E6%8B%A9%E4%B8%80%E4%B8%AA%E8%83%B6%E5%9B%8A.png&quot; alt=&quot;选择一个胶囊&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;全员禁言&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;./%E5%85%A8%E5%91%98%E7%A6%81%E8%A8%80.png&quot; alt=&quot;全员禁言&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;Stack pop&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;./Stack_pop.png&quot; alt=&quot;Stack pop&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;滑稽 CAD&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;./%E6%BB%91%E7%A8%BDCAD.png&quot; alt=&quot;滑稽 CAD&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;滑稽 104 电容&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;./%E6%BB%91%E7%A8%BD104%E7%94%B5%E5%AE%B9.png&quot; alt=&quot;滑稽 104 电容&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;西数红盘: 祝您在新的一年红红火火&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;./%E8%A5%BF%E6%95%B0%E7%BA%A2%E7%9B%98%E7%A5%9D%E6%82%A8%E6%96%B0%E7%9A%84%E4%B8%80%E5%B9%B4%E7%BA%A2%E7%BA%A2%E7%81%AB%E7%81%AB.png&quot; alt=&quot;西数红盘: 祝您在新的一年红红火火&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;聊天开始 I2C&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;./%E8%81%8A%E5%A4%A9%E5%BC%80%E5%A7%8BI2C.png&quot; alt=&quot;聊天开始 I2C&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;聊天停止 I2C&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;./%E8%81%8A%E5%A4%A9%E5%81%9C%E6%AD%A2I2C.png&quot; alt=&quot;聊天停止I2C&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;Go 语言 return&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;GoLang%E5%9B%9E%E8%BD%A6.png&quot; alt=&quot;GoLang回车&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;网络爬虫路由器&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;./%E7%BD%91%E7%BB%9C%E7%88%AC%E8%99%AB%E8%B7%AF%E7%94%B1%E5%99%A8.png&quot; alt=&quot;网络爬虫路由器&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;谷歌验证码: 找出所有 bugs&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;./%E8%B0%B7%E6%AD%8C%E9%AA%8C%E8%AF%81%E7%A0%81_bugs.png&quot; alt=&quot;谷歌验证码-bugs&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;如何百度&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;./%E5%A6%82%E4%BD%95%E7%99%BE%E5%BA%A6.png&quot; alt=&quot;如何百度&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;在线解压&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;./%E5%9C%A8%E7%BA%BF%E8%A7%A3%E5%8E%8B.png&quot; alt=&quot;在线解压&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;电车难题: 重构屎山&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;./%E9%87%8D%E6%9E%84%E5%B1%8E%E5%B1%B1%E7%94%B5%E8%BD%A6%E9%9A%BE%E9%A2%98.png&quot; alt=&quot;重构屎山电车难题&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;千与千寻: 汤婆婆 SQL 注入&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;./%E6%B1%A4%E5%A9%86%E5%A9%86SQL%E6%B3%A8%E5%85%A5.png&quot; alt=&quot;汤婆婆 SQL 注入&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;进度: 我自己做&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;./%E8%BF%9B%E5%BA%A6_%E6%88%91%E8%87%AA%E5%B7%B1%E5%81%9A.png&quot; alt=&quot;进度: 我自己做&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;进度: 正在做了&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;./%E8%BF%9B%E5%BA%A6_%E6%AD%A3%E5%9C%A8%E5%81%9A%E4%BA%86.png&quot; alt=&quot;进度: 正在做了&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;进度: 快快去做&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;./%E8%BF%9B%E5%BA%A6_%E5%BF%AB%E5%BF%AB%E5%8E%BB%E5%81%9A.png&quot; alt=&quot;进度: 快快去做&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;如何截图: 别拍屏幕&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;./%E5%A6%82%E4%BD%95%E6%88%AA%E5%9B%BE%E5%88%AB%E6%8B%8D%E5%B1%8F%E5%B9%95.png&quot; alt=&quot;如何截图别拍屏幕&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;CPU: 听说你低血压&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;./%E5%90%AC%E8%AF%B4%E4%BD%A0%E4%BD%8E%E8%A1%80%E5%8E%8BCPU.png&quot; alt=&quot;听说你低血压CPU&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;给酒精灯加热&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;./%E7%BB%99%E9%85%92%E7%B2%BE%E7%81%AF%E5%8A%A0%E7%83%AD.png&quot; alt=&quot;给酒精灯加热&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;STC 金鼎&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;./STC%E9%87%91%E9%BC%8E.png&quot; alt=&quot;STC金鼎&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;窃格瓦拉: MySQL 从删库到跑路&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;./%E7%AA%83%E6%A0%BC%E7%93%A6%E6%8B%89MySQL%E4%BB%8E%E5%88%A0%E5%BA%93%E5%88%B0%E8%B7%91%E8%B7%AF.gif&quot; alt=&quot;窃格瓦拉MySQL从删库到跑路&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;Explorer: 脑子未响应&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;./%E8%84%91%E5%AD%90%E6%9C%AA%E5%93%8D%E5%BA%94.png&quot; alt=&quot;脑子未响应&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;89C51 滑稽跑马灯&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;./C51%E6%BB%91%E7%A8%BD%E8%B7%91%E9%A9%AC%E7%81%AF.gif&quot; alt=&quot;C51滑稽跑马灯&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;VSCode: 上号&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;./VSCode_%E4%B8%8A%E5%8F%B7.png&quot; alt=&quot;VSCode: 上号&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;VSCode: 我在线上了&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;./VSCode_%E6%88%91%E5%9C%A8%E7%BA%BF%E4%B8%8A%E4%BA%86.png&quot; alt=&quot;VSCode: 我在线上了&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;VSCode: 敲你妈不敲了&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;./VSCode_%E6%95%B2%E4%BD%A0%E5%A6%88%E4%B8%8D%E6%95%B2%E4%BA%86.png&quot; alt=&quot;VSCode: 敲你妈不敲了&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;VSCode: 写你妈不写了&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;./VSCode_%E5%86%99%E4%BD%A0%E5%A6%88%E4%B8%8D%E5%86%99%E4%BA%86.png&quot; alt=&quot;VSCode: 写你妈不写了&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;淘宝精选: 电容手雷&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;./%E6%B7%98%E5%AE%9D%E7%B2%BE%E9%80%89%E7%94%B5%E5%AE%B9%E6%89%8B%E9%9B%B7.png&quot; alt=&quot;淘宝精选电容手雷&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>Carpet 通过命令获取 MC 服务器 MSPT 及 TPS 数据</title><link>https://blog.duckburnincense.com/posts/get-mspt-and-tps-in-fabric-carpet-using-scarpet/</link><guid isPermaLink="true">https://blog.duckburnincense.com/posts/get-mspt-and-tps-in-fabric-carpet-using-scarpet/</guid><description>通过 Fabric-Carpet 的 Scarpet 脚本获取 MC 服务器 MSPT 及 TPS 数据</description><pubDate>Fri, 03 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;先定义两个函数&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/script run mspt()-&amp;gt;(for(last_tick_times(),tot_mspt+=_);tot_mspt/100);
/script run tps()-&amp;gt;return(1000/mspt());
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后就可以获取数据了:&lt;/p&gt;
&lt;p&gt;获取 MSPT:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/script run mspt()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;获取 TPS:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/script run mspt()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;说明: 此处的 TPS 为当前 MSPT 可承载的最大 TPS 数, 如当前 MSPT 为 1, 无 tick 加速. 此时获取的 TPS 并非 20, 而是 1000 / 1 = 1000.&lt;/p&gt;
&lt;p&gt;参考资料:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/gnembon/fabric-carpet/issues/433#issuecomment-680843283&quot;&gt;fabric-carpet#433&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>对于给定网络地址划分指定数量子网及计算子网的详细信息的保姆级教程</title><link>https://blog.duckburnincense.com/posts/step-by-step-guide-to-subnetting-a-network-into-a-specified-number-of-subnets/</link><guid isPermaLink="true">https://blog.duckburnincense.com/posts/step-by-step-guide-to-subnetting-a-network-into-a-specified-number-of-subnets/</guid><description>对于给定网络地址划分指定数量子网及计算子网掩码、网络地址、广播地址、可用地址范围、可用地址数量等信息的保姆级教程, 以 `192.168.10.0/24` 划分 4 个子网为例</description><pubDate>Thu, 18 Sep 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;来看下面这道题目：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IP 地址 192.168.10.0/24
划分 4 个子网
分别写出第一个、第二个、第三个、第四个子网的掩码、网络地址、广播地址、可用地址范围、可用地址数量
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;先把 IP 地址转换成二进制：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;1100 0000.1010 1000.0000 1010.0000 0000
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;上面二进制里的空格只是为了方便阅读&lt;/p&gt;
&lt;p&gt;删掉小数点，这东西只会影响你计算&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;1100 0000 1010 1000 0000 1010 0000 0000
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;接下来看子网掩码：&lt;/p&gt;
&lt;p&gt;题中 “24” 是网络前缀，同样也是在描述子网掩码，只是方法不一样：&lt;/p&gt;
&lt;p&gt;24 是指从前往后有 24 个二进制的 1&lt;/p&gt;
&lt;p&gt;IP（IPv4）地址和子网掩码都是 32 位（二进制数）的长度&lt;/p&gt;
&lt;p&gt;因此，“24” 写出来也就是：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;1111 1111 1111 1111 1111 1111 0000 0000
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果你想看 255.255.255.0 这种形式，可以把上面的二进制每八位加一个小数点&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;1111 1111.1111 1111.1111 1111.0000 0000
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;再每段分别转成十进制&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;255.255.255.0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这样就能互相转换了&lt;/p&gt;
&lt;p&gt;接下来回到正题：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IP 地址：1100 0000 1010 1000 0000 1010 0000 0000
子网掩码：1111 1111 1111 1111 1111 1111 0000 0000
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;根据题目，我们需要在这个 /24 里划分 4 个子网，因此借用一点主机位。&lt;/p&gt;
&lt;p&gt;主机位是啥：&lt;/p&gt;
&lt;p&gt;看子网掩码：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;1111 1111 1111 1111 1111 1111 0000 0000
++++ ++++ ++++ ++++ ++++ ++++ ==== ====
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;其中，1（也就是下面有“+”的位）代表网络位，0 代表主机位（也就是下面有“=”的位）&lt;/p&gt;
&lt;p&gt;如何在 IP 地址中体现出来？&lt;/p&gt;
&lt;p&gt;将 IP 地址和子网掩码两者逐位进行与运算。与运算是啥？&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;A AND B = C
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;若 A 和 B 都是 1，则 C 为 1&lt;/p&gt;
&lt;p&gt;否则（A 或 B 任意一个为 0），C 为 0&lt;/p&gt;
&lt;p&gt;例如：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;1 AND 1 = 1
0 AND 1 = 0
1 AND 0 = 0
0 AND 0 = 0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;那么，我们把 IP 和掩码列出来，逐位进行与运算&lt;/p&gt;
&lt;p&gt;（第一行为 IP，第二行为掩码，第四行是与运算的结果）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;1100 0000 1010 1000 0000 1010 0000 0000
1111 1111 1111 1111 1111 1111 0000 0000
==== ==== ==== ==== ==== ==== ==== ====
1100 0000 1010 1000 0000 1010 0000 0000
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;不要关心结果，自己算一下，注意过程。不难发现，只要子网掩码里有 0，结果就一定是 0；子网掩码里是 1，结果就取决于 IP。这样子网掩码就成功地“掩”上了主机位，只剩下了网络位&lt;/p&gt;
&lt;p&gt;也就是无论主机位怎么变化，都能被“掩”上，不会影响网络位&lt;/p&gt;
&lt;p&gt;如果你还是没注意到，看这（这个例子的 IP 是我随便写的，不用关心）：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;这些（%）下面的数字，
全部都是原样搬到结果里面 ↓        ↓ 这里无论是什么，都不会在结果里
%%%% %%%% %%%% %%%% %%%% %%%% ↓↓↓↓ ↓↓↓↓
1100 0000 1010 1000 0000 1010 1010 0101
1111 1111 1111 1111 1111 1111 0000 0000 ← 这里是 0
==== ==== ==== ==== ==== ==== ==== ====
1100 0000 1010 1000 0000 1010 0000 0000
#### #### #### #### #### #### ↑↑↑↑ ↑↑↑↑
这些（#）上面的数字，            ↑ 结果永远是 0
全部都是原样来自于 IP 里面
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;那主机位是啥？&lt;/p&gt;
&lt;p&gt;就是被掩上的部分，比如最开始的题目里，被掩上的就是 &lt;code&gt;0000 0000&lt;/code&gt;；上一个例子里，是 &lt;code&gt;1010 0101&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;我知道你现在很想把它们都写成点分十进制，但你别写，用二进制算。&lt;/p&gt;
&lt;p&gt;回到最开始的题目：&lt;/p&gt;
&lt;p&gt;我们需要在这个 /24 里划分 4 个子网，因此需要借用一点主机位来划分子网。&lt;/p&gt;
&lt;p&gt;如何确定要借用多少位？&lt;/p&gt;
&lt;p&gt;先来看：如果借用 1 位（二进制位），则只有：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;0
1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;那么只有两个子网，显然不够，继续：&lt;/p&gt;
&lt;p&gt;借用 2 位：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;00
01
10
11
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;有四个子网了，够了&lt;/p&gt;
&lt;p&gt;假设我们要划 7 个子网，还不够咋办？接着划。此时借用 3 位：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;000
001
010
011
100
101
110
111
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;现在有 8 个子网，够了。&lt;/p&gt;
&lt;p&gt;可以注意到，借用 n 位得到的可用子网数量就是 2 的 n 次方&lt;/p&gt;
&lt;p&gt;比如借用 1 位，数量是 2 的 1 次方，就是 2；&lt;/p&gt;
&lt;p&gt;借用 2 位，2 的 2 次方，就是 4；&lt;/p&gt;
&lt;p&gt;借用 3 位，2 的 3 次方，就是 8。以此类推&lt;/p&gt;
&lt;p&gt;回到借用 2 位：&lt;/p&gt;
&lt;p&gt;那么我们的子网掩码就由&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;1111 1111 1111 1111 1111 1111 0000 0000
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;变成了&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;1111 1111 1111 1111 1111 1111 1100 0000
                              ↑↑
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;因此借用完成后的子网掩码转换成点分十进制就是&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;255.255.255.192
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;好了，忘掉这个点分十进制吧，用二进制&lt;/p&gt;
&lt;p&gt;可以注意到，我们借用了两位主机位，用来划分子网：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;1111 1111 1111 1111 1111 1111 1100 0000
                              ↑↑
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;那么放到 IP 地址里看就是这样：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;                              ↓ 这两位
                              ↓↓
1100 0000 1010 1000 0000 1010 0000 0000
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;两个空位，0 和 1 排列组合：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;00
01
10
11
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;也套到 IP 地址里：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;                              ↓ 这两位
                              ↓↓
1100 0000 1010 1000 0000 1010 0000 0000
1100 0000 1010 1000 0000 1010 0100 0000
1100 0000 1010 1000 0000 1010 1000 0000
1100 0000 1010 1000 0000 1010 1100 0000
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这就是我们划分出的四个子网了。&lt;/p&gt;
&lt;p&gt;如果你就是想看点分十进制，它们依次是：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;192.168.10.0
192.168.10.64
192.168.10.128
192.168.10.192
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;接下来来看网络地址、广播地址、可用地址范围&lt;/p&gt;
&lt;p&gt;首先，网络地址就是主机位全是 0 的地址：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;                                ↓ 这六位是主机位
                                ↓↓ ↓↓↓↓
1100 0000 1010 1000 0000 1010 0000 0000
1100 0000 1010 1000 0000 1010 0100 0000
1100 0000 1010 1000 0000 1010 1000 0000
1100 0000 1010 1000 0000 1010 1100 0000
                              ↑↑
                              ↑ 这两位是刚才借走拿去划子网的主机位，
                                现在它们不属于主机位了，叫做子网位
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如上，“这六位是主机位” 的箭头所指向的就是主机位，下面的箭头是我们借用了原来的 2 位主机位，这两位现在不再代表主机，而是用来标识子网，我们称之为&quot;子网位&quot;&lt;/p&gt;
&lt;p&gt;因此，新的网络前缀是 24（原网络位） + 2（子网位） = 26 位。剩下的 6 位才是新的主机位&lt;/p&gt;
&lt;p&gt;主机位全 0 就是网络地址，因此，它们的网络地址就是&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;1100 0000 1010 1000 0000 1010 0000 0000
1100 0000 1010 1000 0000 1010 0100 0000
1100 0000 1010 1000 0000 1010 1000 0000
1100 0000 1010 1000 0000 1010 1100 0000
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;点分十进制：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;192.168.10.0
192.168.10.64
192.168.10.128
192.168.10.192
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;请注意，第一个子网的网络地址（192.168.10.0）和原始网络的网络地址是相同的，这是正常现象&lt;/p&gt;
&lt;p&gt;广播地址是主机位全是 1 的 IP 地址：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;                                ↓ 这六位是主机位
                                ↓↓ ↓↓↓↓
1100 0000 1010 1000 0000 1010 0011 1111
1100 0000 1010 1000 0000 1010 0111 1111
1100 0000 1010 1000 0000 1010 1011 1111
1100 0000 1010 1000 0000 1010 1111 1111
                              ↑↑
                              ↑ 这两位是刚才借走拿去划子网的主机位，
                                现在它们不属于主机位了
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;因此，它们的广播地址写成点分十进制就是：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;192.168.10.63
192.168.10.127
192.168.10.191
192.168.10.255
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;接下来来看可用地址范围。一个网段除了全 0（网络地址）和全 1（广播地址），其余均可使用&lt;/p&gt;
&lt;p&gt;因此，以&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;1100 0000 1010 1000 0000 1010 0000 0000
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;（192.168.10.0）为例，它的可用范围就是&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;                                ↓ 注意这里
                                ↓↓ ↓↓↓↓
1100 0000 1010 1000 0000 1010 0000 0000 ← 这个主机位全 0，是网络地址，用不了
1100 0000 1010 1000 0000 1010 0000 0001 ← (注意看主机位：000001) 从这开始
1100 0000 1010 1000 0000 1010 0000 0010
太多了列不完省略部分...
1100 0000 1010 1000 0000 1010 0011 1101
1100 0000 1010 1000 0000 1010 0011 1110 ← (注意看主机位：111110) 一直到这，都可以用 
1100 0000 1010 1000 0000 1010 0011 1111 ← 这个主机位全 1，是广播地址，用不了
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;因此，可用地址数量就是 6 位二进制数不重复的情况下能排列组合出的所有数字减掉 2（全 0 和全 1），也就是 2 的六次方减 2 = 64 - 2 = 62&lt;/p&gt;
&lt;p&gt;可用地址范围（转成点分十进制）就是&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;192.168.10.1 ~ 192.168.10.62
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;以此类推，四个子网的可用地址范围就是&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;192.168.10.1 ~ 192.168.10.62
192.168.10.65 ~ 192.168.10.126
192.168.10.129 ~ 192.168.10.190
192.168.10.193 ~ 192.168.10.254
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;所以题目最终的答案就是：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;子网&lt;/th&gt;
&lt;th&gt;子网掩码&lt;/th&gt;
&lt;th&gt;网络地址&lt;/th&gt;
&lt;th&gt;广播地址&lt;/th&gt;
&lt;th&gt;可用地址范围&lt;/th&gt;
&lt;th&gt;可用地址数量&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;子网 1&lt;/td&gt;
&lt;td&gt;255.255.255.192&lt;/td&gt;
&lt;td&gt;192.168.10.0&lt;/td&gt;
&lt;td&gt;192.168.10.63&lt;/td&gt;
&lt;td&gt;192.168.10.1   ~ 192.168.10.62&lt;/td&gt;
&lt;td&gt;62&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;子网 2&lt;/td&gt;
&lt;td&gt;255.255.255.192&lt;/td&gt;
&lt;td&gt;192.168.10.64&lt;/td&gt;
&lt;td&gt;192.168.10.127&lt;/td&gt;
&lt;td&gt;192.168.10.65  ~ 192.168.10.126&lt;/td&gt;
&lt;td&gt;62&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;子网 3&lt;/td&gt;
&lt;td&gt;255.255.255.192&lt;/td&gt;
&lt;td&gt;192.168.10.128&lt;/td&gt;
&lt;td&gt;192.168.10.191&lt;/td&gt;
&lt;td&gt;192.168.10.129 ~ 192.168.10.190&lt;/td&gt;
&lt;td&gt;62&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;子网 4&lt;/td&gt;
&lt;td&gt;255.255.255.192&lt;/td&gt;
&lt;td&gt;192.168.10.192&lt;/td&gt;
&lt;td&gt;192.168.10.255&lt;/td&gt;
&lt;td&gt;192.168.10.193 ~ 192.168.10.254&lt;/td&gt;
&lt;td&gt;62&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&amp;lt;!--
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Author: &lt;a href=&quot;mailto:DuckBurnIncense@outlook.com&quot;&gt;DuckBurnIncense&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Last edit: 2025-09-18 20:30&lt;/p&gt;
&lt;p&gt;This work is licensed under Creative Commons Attribution-NonCommercial 4.0 International. To view a copy of this license, visit https://creativecommons.org/licenses/by-nc/4.0/&lt;/p&gt;
&lt;p&gt;(End) --&amp;gt;&lt;/p&gt;
</content:encoded></item><item><title>常用空间搜索引擎备忘录</title><link>https://blog.duckburnincense.com/posts/commonly-used-cyberspace-mapping-search-engine/</link><guid isPermaLink="true">https://blog.duckburnincense.com/posts/commonly-used-cyberspace-mapping-search-engine/</guid><description>记录一些常用的空间搜索引擎</description><pubDate>Tue, 18 Feb 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;https://search.censys.io&quot;&gt;Censys&lt;/a&gt;: Censys 联网设备信息搜索引擎&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://fofa.so/&quot;&gt;FOFA.so&lt;/a&gt;: FOFA.so 网络空间搜索引擎, Query Credits 300/month, 3k Results/month&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.zoomeye.org/&quot;&gt;ZoomEye&lt;/a&gt;: 每月最大查询结果数	3,000, 最大可查看页数	5&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://quake.360.cn/quake/&quot;&gt;360 网络空间资产测绘&lt;/a&gt;: 360 QUAKE 网络空间资产测绘&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://spyse.com/&quot;&gt;Spyse&lt;/a&gt;: Spyse - 互联网资产搜索引擎&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.shodan.io/&quot;&gt;Shodan&lt;/a&gt;: Shodan 网络空间设备搜索引擎&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.onyphe.io/&quot;&gt;ONYPHE&lt;/a&gt;: ONYPHE - Cyber Defense Search Engine&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://dnsdb.io/&quot;&gt;DNSDB&lt;/a&gt;: DNSDB - 全球 DNS 搜索引擎&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://hunter.qianxin.com/&quot;&gt;鹰图&lt;/a&gt;: 鹰图平台 (hunter) - 奇安信网络空间测绘系统&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://fullhunt.io/&quot;&gt;FullHunt&lt;/a&gt;: FullHunt | Expose Your Attack Surface&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://hunter.how/&quot;&gt;Hunter&lt;/a&gt;: Full Port Coverage, Up to 10,000 API Results per 30 Days, Daily Query Limit 100&lt;/p&gt;
</content:encoded></item></channel></rss>