<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>晴雨笔记</title><description>素白清韵，简静安然</description><link>https://memo.moieo.net/</link><language>zh_CN</language><item><title>Vibe Coding 实战：用 AI 从零写了一个短链接平台</title><link>https://memo.moieo.net/2026/05/23/153933/</link><guid isPermaLink="true">https://memo.moieo.net/2026/05/23/153933/</guid><pubDate>Sat, 23 May 2026 07:39:33 GMT</pubDate><content:encoded>&lt;p&gt;最近 Vibe Coding 挺火的，我也试了一把——把需求写成完整的 prompt 丢给 AI，让它从零写了一个短链接服务平台。&lt;/p&gt;
&lt;p&gt;项目是逐步长起来的：先给 AI 一份核心需求的 prompt 做一版，然后不断提新需求让 AI 迭代。看 Git 提交记录就能看出来这个演进过程。&lt;/p&gt;
&lt;p&gt;记录一下我用的 prompt 原文、后续加了哪些功能、以及测试中踩的坑。&lt;/p&gt;
&lt;p&gt;项目开源地址：&lt;a href=&quot;https://github.com/moieo/qingyu-short&quot;&gt;GitHub&lt;/a&gt; · &lt;a href=&quot;https://gitee.com/moieo/qingyu-short&quot;&gt;Gitee&lt;/a&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;初始 prompt&lt;/h2&gt;
&lt;p&gt;以下是第一批发给 AI 的完整内容：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;你是全栈开发工程师，精通 Nextjs 框架，请完成以下任务：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;在项目中添加 Radix-UI 框架&lt;/li&gt;
&lt;li&gt;实现 Nextjs 后端，连接 PostgreSQL 数据库&lt;/li&gt;
&lt;li&gt;实现多用户管理（多个管理员和用户，管理员可以精确管理每个用户创建的短网址）&lt;/li&gt;
&lt;li&gt;实现创建短网址功能，支持设置有效期（n小时/n天/n月/n年），或者年月日时分秒，永久（设计为用户权限）&lt;/li&gt;
&lt;li&gt;实现短网址的密码保护功能，输入正确的授权码才能访问（随机生成 6 位纯数字密码）或者设定文本密码，默认随机生成 6 位密码，或者无密码&lt;/li&gt;
&lt;li&gt;实现过期的短网址自动清理（兼容 Serverless，管理员可关闭）&lt;/li&gt;
&lt;li&gt;暴露 API 接入功能，用户可以通过 token 验证来接入短网址生成，管理员可控制用户权限&lt;/li&gt;
&lt;li&gt;仅管理员可创建用户，限制至少保留一个管理员账户&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;要求：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;用户界面美观，使用 Radix-UI 框架&lt;/li&gt;
&lt;li&gt;保持 UI 框架原有的样式，CSS 只用于控制布局而不是样式，实现夜间/日间模式&lt;/li&gt;
&lt;li&gt;代码合理分文件，代码注释合理，方便人工阅读和维护&lt;/li&gt;
&lt;li&gt;完成后编写 README.md 文件&lt;/li&gt;
&lt;li&gt;用户界面中不使用 Emoji 等表情，一律使用字体图标替代&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;事项：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;已安装好 PostgreSQL 在 Podman 中，可以通过 172.20.1.5:5432 连接&lt;/li&gt;
&lt;li&gt;数据库操作请使用 podman exec&lt;/li&gt;
&lt;li&gt;项目测试请创建使用 shorturl 用户/数据库&lt;/li&gt;
&lt;li&gt;使用 Prisma.js 连接数据库，方便后期添加其他数据库支持&lt;/li&gt;
&lt;li&gt;编写 package.json 中的运行命令，快速创建数据库相关内容&lt;/li&gt;
&lt;li&gt;编写打包并运行的 package.json script 指令&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;AI 基于这份 prompt 生成了项目骨架：数据模型、认证系统、短链接核心 CRUD、管理后台、Docker 部署。Git 记录上看大概是这几个提交：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;7458a3e  初始化项目结构和数据库模型
6653133  添加 Radix-UI 组件库和主题系统
8c2a559  实现用户认证系统
59d7555  实现短链接核心功能
caa69ee  添加管理后台和系统功能
d5d2372  添加 Docker 支持和文档
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;后面陆续加的功能&lt;/h2&gt;
&lt;p&gt;第一版跑起来之后，我又陆续给 AI 提了新需求，功能是一步步叠加上去的：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;多域名支持&lt;/strong&gt; — 同一个短码在不同域名下独立，互不干扰。还加了域名级别的 HTTPS 开关。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;IP 地理定位&lt;/strong&gt; — 访问记录里显示访客所在省份。用的离线 IP 库，不调外部接口。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;安全审计日志&lt;/strong&gt; — 在 middleware 里无侵入记录每次请求，格式对标 ISO 27001。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;API Key 加密存储&lt;/strong&gt; — 密钥用 AES-256-GCM 加密，查库用 SHA-256 哈希，不是明文存。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;SQLite 支持&lt;/strong&gt; — 后期加的，entrypoint 脚本根据环境变量自动切换 PostgreSQL 或 SQLite，方便不同场景部署。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;分页系统&lt;/strong&gt; — 链接列表和用户列表支持分页，可调每页条数。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;复制模板&lt;/strong&gt; — 管理员可以写 JS 模板函数，自定义复制短链接时的格式。&lt;/p&gt;
&lt;p&gt;看 Git 记录，项目从第一个核心功能到现在的完整状态，经历了 50+ 次提交，大部分都是「提需求 → AI 实现 → 测试验证 → 有问题再修」的循环。&lt;/p&gt;
&lt;h2&gt;踩的坑&lt;/h2&gt;
&lt;p&gt;测试过程中发现的主要问题：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;访问次数为 0 还能用&lt;/strong&gt; — 创建短链接时设了访问次数上限，用完后依然能正常跳转。把测试现象告诉 AI，它自己定位修了。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Docker 构建原生模块报错&lt;/strong&gt; — &lt;code&gt;ts-ip2region2&lt;/code&gt; 依赖 C++ 编译，构建环境和运行环境不一致导致 &lt;code&gt;.node&lt;/code&gt; 文件缺失。折腾了几轮才在 Dockerfile 里正确处理好预编译产物的复制。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;有效期解析边界&lt;/strong&gt; — 某些格式的过期时间解析不对，测试发现后让 AI 修了。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;SQLite 兼容性问题&lt;/strong&gt; — 后期加 SQLite 支持时，Prisma 的 enum 类型在 SQLite 里不支持，需要改成 string 类型，还有一些查询语法差异，逐个修了。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;环境差异&lt;/strong&gt; — AI 的开发环境和 Docker 构建环境不一致，Node 版本、系统库不同导致各种小问题，反复对齐。&lt;/p&gt;
&lt;h2&gt;一点感受&lt;/h2&gt;
&lt;p&gt;这次试下来最大的体会是：&lt;strong&gt;Vibe Coding 不是一次性把需求说清楚就完事了&lt;/strong&gt;，项目是长出来的。&lt;/p&gt;
&lt;p&gt;初始 prompt 决定了项目骨架，后续迭代才是血肉。每加一个功能，就是一段「提需求 → AI 实现 → 测试验证」的小循环。50 多次提交看下来，AI 写代码的效率确实高，但需求分解、功能设计、测试验证这些事还是得人来做。&lt;/p&gt;
&lt;p&gt;写 prompt 本身就是在做架构设计——选什么技术栈、功能怎么拆、约束条件是什么，这些不想清楚，AI 也帮不了你。&lt;/p&gt;
&lt;p&gt;网上常看到「文科生用 AI 也能做软件」的说法，好像不需要任何专业知识就能做出产品。但我的实际体验是：&lt;strong&gt;你不会因为有了 AI 就突然会做软件，你只是把写代码的活儿外包了而已&lt;/strong&gt;。需求分析、功能设计、测试验证、部署运维，这些环节一个都少不了。不会因为你用了 AI，产品需求就能自动变清晰，bug 就能自动消失，部署就能一次成功。&lt;/p&gt;
&lt;p&gt;AI 降低了写代码的门槛，但没有降低做产品的门槛。&lt;/p&gt;
</content:encoded></item><item><title>Astro &amp; Fuwari优化配置</title><link>https://memo.moieo.net/2025/09/21/143106/</link><guid isPermaLink="true">https://memo.moieo.net/2025/09/21/143106/</guid><pubDate>Sun, 21 Sep 2025 06:31:06 GMT</pubDate><content:encoded>&lt;h2&gt;Twikoo评论区 💬&lt;/h2&gt;
&lt;p&gt;具体后端部署请参考 &lt;a href=&quot;https://twikoo.js.org/&quot;&gt;Twikoo&lt;/a&gt; 哦～ 我给相关代码添加了两个响应事件，解决了需要刷新一次才能显示的小问题呢！😊&lt;/p&gt;
&lt;p&gt;新增编辑相关文件&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;div id=&quot;tcomment&quot;&amp;gt;&amp;lt;/div&amp;gt;

&amp;lt;script is:inline&amp;gt;
  window.twikooIsRun = false;

  function loadTwikoo() {
    if (window.twikooIsRun) return;
    const commentsContainer = document.getElementById(&quot;tcomment&quot;);
    if (commentsContainer) {
      const script = document.createElement(&quot;script&quot;);
      script.src =
        &quot;https://registry.npmmirror.com/twikoo/1.6.44/files/dist/twikoo.min.js&quot;;
      script.onload = () =&amp;gt; {
        const initScript = document.createElement(&quot;script&quot;);
        initScript.innerHTML = `
            twikoo.init({
                envId: &apos;https://xxx&apos;,
                el: &apos;#tcomment&apos;,
            });
        `;
        document.body.appendChild(initScript);
        window.twikooIsRun = true;
      };
      document.body.appendChild(script);
    }
  }
  document.addEventListener(&quot;astro:page-load&quot;, loadTwikoo);
  document.addEventListener(&quot;DOMContentLoaded&quot;, loadTwikoo);
&amp;lt;/script&amp;gt;

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;添加到喜欢的位置，比如我底部的评论区就很合适呀～&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;---
import Comment from &quot;@components/Comment.astro&quot;;
---
...
&amp;lt;Markdown class=&quot;mb-6 markdown-content onload-animation&quot;&amp;gt;
  &amp;lt;Content /&amp;gt;
&amp;lt;/Markdown&amp;gt;
{
  licenseConfig.enable &amp;amp;&amp;amp; (
    &amp;lt;License
      title={entry.data.title}
      slug={entry.slug}
      pubDate={entry.data.published}
      class=&quot;mb-6 rounded-xl license-container onload-animation&quot;
    /&amp;gt;
  )
}

&amp;lt;Comment /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;底部计时功能 ⏳&lt;/h2&gt;
&lt;p&gt;实时显示本站运行时长哦～ 是不是很贴心！💕&lt;/p&gt;
&lt;p&gt;添加配置项&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;export type SiteConfig = {
	date: Date
};
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;export const siteConfig: SiteConfig = {
	date: new Date(&apos;2020-04-15 00:00:00&apos;)
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;需要新增以下文件&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;script&amp;gt;
import { siteConfig } from &apos;@/config&apos;;

let days, hours, minutes, seconds;

function updateEstablishedTime() {
  var now = new Date();
  var difference = now.getTime() - siteConfig.date.getTime();
  days = Math.floor(difference / (1000 * 60 * 60 * 24));
  hours = Math.floor((difference % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
  minutes = Math.floor((difference % (1000 * 60 * 60)) / (1000 * 60));
  seconds = Math.floor((difference % (1000 * 60)) / 1000);
  setTimeout(updateEstablishedTime, 1000);
}

updateEstablishedTime();
&amp;lt;/script&amp;gt;

&amp;lt;span&amp;gt;
  本站已稳定运行 {days} 天 {hours} 小时 {minutes} 分钟 {seconds} 秒
&amp;lt;/span&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在网站底部引用相关文件就好啦～&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;---
import { Icon } from &quot;astro-icon/components&quot;;
import RunningTime from &quot;./RunningTime.svelte&quot;;
---
&amp;lt;div class=&quot;transition text-50 text-sm text-center&quot;&amp;gt;
  &amp;amp;copy; &amp;lt;span id=&quot;copyright-year&quot;&amp;gt;{currentYear}&amp;lt;/span&amp;gt; {profileConfig.name}. All Rights Reserved. /
  &amp;lt;a class=&quot;transition link text-[var(--primary)] font-medium&quot; target=&quot;_blank&quot; href={url(&apos;rss.xml&apos;)}&amp;gt;RSS&amp;lt;/a&amp;gt; /
  &amp;lt;a class=&quot;transition link text-[var(--primary)] font-medium&quot; target=&quot;_blank&quot; href={url(&apos;sitemap-index.xml&apos;)}&amp;gt;Sitemap&amp;lt;/a&amp;gt;&amp;lt;br&amp;gt;
  &amp;lt;div class=&quot;flex items-center justify-center gap-1&quot;&amp;gt;&amp;lt;Icon name=&apos;fa6-solid:heart&apos; class=&quot;text-[0.8rem] text-red-500 animate-pulse&quot;&amp;gt;&amp;lt;/Icon&amp;gt;&amp;lt;RunningTiclient:load /&amp;gt;&amp;lt;/div&amp;gt;
  Powered by
  &amp;lt;a class=&quot;transition link text-[var(--primary)] font-medium&quot; target=&quot;_blank&quot; href=&quot;https://astro.build&quot;&amp;gt;Astro&amp;lt;/a&amp;gt; &amp;amp;
  &amp;lt;a class=&quot;transition link text-[var(--primary)] font-medium&quot; target=&quot;_blank&quot; href=&quot;https://github.com/saicaca/fuwari&quot;&amp;gt;Fuwari&amp;lt;/a&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Arch Linux UEFI 安装指南：Btrfs 子卷 + GNOME 桌面环境</title><link>https://memo.moieo.net/2025/05/26/223735/</link><guid isPermaLink="true">https://memo.moieo.net/2025/05/26/223735/</guid><pubDate>Mon, 26 May 2025 14:37:35 GMT</pubDate><content:encoded>&lt;p&gt;&lt;strong&gt;声明：原作者信息&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;哔哩哔哩主页：&lt;a href=&quot;https://space.bilibili.com/2017026819&quot;&gt;https://space.bilibili.com/2017026819&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Github主页：&lt;a href=&quot;https://github.com/FireflyAyaka&quot;&gt;https://github.com/FireflyAyaka&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;QQ号：2037566388&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;温馨提示&lt;/strong&gt;：本教程仅适用于UEFI设备 (包括虚拟机模拟UEFI或真机UEFI)。使用传统BIOS(Legacy)设备的，&lt;strong&gt;出门左拐，找其他教程去&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;🎒 准备开始&lt;/h2&gt;
&lt;h3&gt;需要准备的东西&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;最新版的&lt;a href=&quot;https://mirrors.jxust.edu.cn/archlinux/iso/latest/archlinux-x86_64.iso&quot;&gt;Arch Linux ISO镜像文件&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;一个U盘(如果你要在实体机安装的话)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;重要注意事项&lt;/h3&gt;
&lt;p&gt;✨ &lt;strong&gt;安全小贴士&lt;/strong&gt; ✨&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;备份好所有重要数据&lt;/li&gt;
&lt;li&gt;操作有风险，三思而后行&lt;/li&gt;
&lt;li&gt;如果是第一次尝试，&lt;strong&gt;强烈建议先在虚拟机里练习&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;🖥️ 启动Live环境&lt;/h2&gt;
&lt;h3&gt;启动方式选择&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;使用虚拟机：直接加载下载好的ISO镜像启动&lt;/li&gt;
&lt;li&gt;使用实体机：需要用工具把ISO写入U盘后从U盘启动&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;💾 一、磁盘分区与配置&lt;/h2&gt;
&lt;h3&gt;1. 使用cfdisk分区工具&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;cfdisk /dev/sda
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;分区步骤详解&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;初始化磁盘格式&lt;/strong&gt;：选择 &lt;code&gt;gpt&lt;/code&gt; 选项&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;创建EFI系统分区&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;大小设置为500M&lt;/li&gt;
&lt;li&gt;类型选 &lt;code&gt;EFI System&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;创建根分区&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;使用剩下的所有空间&lt;/li&gt;
&lt;li&gt;类型选择 &lt;code&gt;Linux root (x86-64)&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;分区表示例&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;Disk: /dev/sda
Size: 64GiB
Label: gpt
Device    Start   End       Size  Type
/dev/sda1 2048    1026047   500M  EFI System
/dev/sda2 1026048 134215679 63.5G Linux root (x86-64)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;选择&lt;code&gt;Write&lt;/code&gt;写入分区表
输入&lt;code&gt;yes&lt;/code&gt;确认写入
选择&lt;code&gt;quit&lt;/code&gt;退出程序&lt;/p&gt;
&lt;h3&gt;2. 格式化分区操作&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 格式化EFI分区为FAT32格式
mkfs.fat -F32 -n &quot;arch-efi&quot; /dev/sda1

# 格式化根分区为Btrfs格式
mkfs.btrfs -L &quot;arch-root&quot; /dev/sda2
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3. Btrfs子卷设置&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 先挂载根分区
mount /dev/sda2 /mnt

# 创建必要的子卷
btrfs subvolume create /mnt/@            # 根目录子卷
btrfs subvolume create /mnt/@home        # 用户目录子卷

# 临时卸载
umount /mnt
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4. 创建挂载点结构（请在挂载@子卷后执行）&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 创建必要的目录结构
mkdir -p /mnt/{boot/efi,home}

# 挂载EFI分区
mount /dev/sda1 /mnt/boot/efi
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5. 分情况挂载磁盘&lt;/h3&gt;
&lt;p&gt;根据你的硬件配置选择并执行合适的挂载命令：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;实体机（SSD，2017年及以后的CPU）：&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;mount -o subvol=@,compress=zstd:3,noatime,ssd /dev/sda2 /mnt # 挂载主卷
mount -o subvol=@home,compress=zstd:4,noatime,ssd /dev/sda2 /mnt/home # 挂载用户卷
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;实体机（SSD，2016年及以前的CPU）：&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;mount -o subvol=@,compress=zstd:2,noatime,ssd /dev/sda2 /mnt # 挂载主卷
mount -o subvol=@home,compress=zstd:3,noatime,ssd /dev/sda2 /mnt/home # 挂载用户卷
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;虚拟机（虚拟磁盘文件存放在SSD，&lt;em&gt;&lt;strong&gt;注意不是虚拟磁盘模拟SSD！&lt;/strong&gt;&lt;/em&gt;）：&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;mount -o subvol=@,compress=zstd:1,noatime,ssd /dev/sda2 /mnt # 挂载主卷
mount -o subvol=@home,compress=zstd:2,noatime,ssd /dev/sda2 /mnt/home # 挂载用户卷
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;HDD（实体机HDD/虚拟磁盘文件存放在HDD）：&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;mount -o subvol=@,compress=lzo,noatime /dev/sda2 /mnt # 挂载主卷
mount -o subvol=@home,compress=lzo,noatime /dev/sda2 /mnt/home # 挂载用户卷
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;不确定CPU发布年份，但只确定使用SSD（实体机SSD/虚拟磁盘文件存放在SSD）：&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;mount -o subvol=@,compress=auto,noatime,ssd /dev/sda2 /mnt # 挂载主卷
mount -o subvol=@home,compress=auto,noatime,ssd /dev/sda2 /mnt/home # 挂载用户卷
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;不确定CPU发布年份，但只确定使用HDD（实体机HDD/虚拟磁盘文件存放在HDD）或完全不确定：&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;mount -o subvol=@,compress=auto,noatime /dev/sda2 /mnt # 挂载主卷
mount -o subvol=@home,compress=auto,noatime /dev/sda2 /mnt/home # 挂载用户卷
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;📦 二、安装基础系统&lt;/h2&gt;
&lt;h3&gt;1. 配置pacman&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;nano /etc/pacman.conf
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;找到并取消注释 &lt;code&gt;Color&lt;/code&gt;&lt;br /&gt;
在下面添加 &lt;code&gt;ILoveCandy&lt;/code&gt;&lt;br /&gt;
在文件末尾添加以下内容：\&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[archlinuxcn]
Server = https://mirrors.163.com/archlinux-cn/$arch
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;必做！&lt;/strong&gt; 不加这个到时候你&lt;code&gt;pacstrap&lt;/code&gt;装不了&lt;code&gt;paru&lt;/code&gt;！（&lt;code&gt;paru&lt;/code&gt;相关详见Q&amp;amp;A）&lt;br /&gt;
完事后保存，然后添加archlinuxcn密钥：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pacman-key --lsign-key &apos;farseerfc@archlinux.org&apos;
pacman -Sy archlinuxcn-keyring
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;（拍桌）&lt;strong&gt;重要操作！&lt;/strong&gt; 这一步相当于给软件源上一把锁，不做的话后面装软件会报错到怀疑人生～&lt;/p&gt;
&lt;h3&gt;2. 使用国内镜像加速&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 设置镜像源
echo &apos;Server = https://mirrors.jxust.edu.cn/archlinux/$repo/os/$arch&apos; &amp;gt; /etc/pacman.d/mirrorlist # 江西理工大学是一个很快的镜像源，比隔壁北外都快（北外最近开始限速了）
echo &apos;Server = https://mirrors.163.com/archlinux/$repo/os/$arch&apos; &amp;gt;&amp;gt; /etc/pacman.d/mirrorlist # 可选，添加该备用源后可在江西理工大学镜像源不可用时让冈门替补

# 刷新软件包数据库
pacman -Syy
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3. 安装基本系统&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;pacstrap /mnt base base-devel linux-zen linux-zen-headers linux-firmware htop cpupower nano dhcpcd net-tools networkmanager iw wpa_supplicant bluez bluez-utils grub efibootmgr sudo doas snapper fastfetch paru # 这里paru来自archlinuxcn源
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;⚙️ 三、系统基础配置&lt;/h2&gt;
&lt;h3&gt;1. 生成fstab&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;genfstab -U /mnt &amp;gt;&amp;gt; /mnt/etc/fstab
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2. 进入新系统环境&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;arch-chroot /mnt
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3. 本地化设置&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 设置中文locale
nano /etc/locale.gen  # 取消注释 zh_CN.UTF-8 UTF-8
locale-gen

# 设置默认语言
echo LANG=zh_CN.UTF-8 &amp;gt; /etc/locale.conf

# 设置时区
ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime # 这里没有北京，只有上海～

# 同步硬件时钟
hwclock --systohc --utc
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4. 网络相关配置&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 设置主机名(示例主机名ayaka，因为原作者是个绫华厨！可以改成你喜欢的名字)
echo ayaka &amp;gt; /etc/hostname

# 启用网络服务
systemctl enable dhcpcd # DHCP
systemctl enable NetworkManager # WiFi和有线
systemctl enable bluetooth  # 蓝牙
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5. 用户账户管理&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 设置root密码
passwd root

# 创建普通用户(示例用户名为firefly，因为原作者也是个流萤厨！可以改成你喜欢的名字)
useradd -m -g users -G wheel -s /bin/bash firefly

# 设置用户密码(记得将“firefly”改为你的用户名)
passwd firefly
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;6. 配置sudo和doas&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;配置sudo：&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;EDITOR=nano visudo
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在文件末尾添加以下内容（记得将“firefly”改为你的用户名）：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;%wheel ALL=(ALL:ALL) ALL
%sudo ALL=(ALL:ALL) ALL
firefly ALL=(ALL:ALL) ALL
Defaults pwfeedback
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;配置doas（双重保险！不加这个到时候sudo炸了你就老实了）：&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;nano /etc/doas.conf
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;添加以下内容（记得将“firefly”改为你的用户名）：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;permit persist keepenv setenv { -ENV LANG=zh_CN.UTF-8 } root as root
permit persist keepenv setenv { -ENV LANG=zh_CN.UTF-8 } :wheel as root
permit persist keepenv setenv { -ENV LANG=zh_CN.UTF-8 } :sudo as root
permit persist keepenv setenv { -ENV LANG=zh_CN.UTF-8 } firefly as root
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;7. 安装引导程序&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 安装GRUB引导
grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=&apos;Arch Linux&apos;

# 生成GRUB配置
grub-mkconfig -o /boot/grub/grub.cfg

# 生成initramfs
echo &apos;HOOKS=(base udev autodetect microcode modconf kms keyboard keymap consolefont block filesystems btrfs fsck)&apos; &amp;gt;&amp;gt; /etc/mkinitcpio.conf
mkinitcpio -p linux-zen
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;8. 完成安装，准备重启&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 退出chroot环境
exit

# 卸载所有分区
umount -R /mnt

# 重启进入新系统
reboot
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;🖥️ 四、安装图形界面&lt;/h2&gt;
&lt;h3&gt;1. 登录新系统&lt;/h3&gt;
&lt;p&gt;使用之前设置的用户名和密码登录tty终端，随后输入以下命令并回车：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;LANG=C
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2. 配置pacman&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;sudo nano /etc/pacman.conf
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;找到并取消注释 &lt;code&gt;Color&lt;/code&gt;&lt;br /&gt;
在下面添加 &lt;code&gt;ILoveCandy&lt;/code&gt;&lt;br /&gt;
在文件末尾添加以下内容：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[archlinuxcn]
Server = https://mirrors.163.com/archlinux-cn/$arch
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;必做！&lt;/strong&gt; 不做这一步你到时候没法更新&lt;code&gt;paru&lt;/code&gt;！
完事后保存，然后添加archlinuxcn密钥：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo pacman-key --lsign-key &apos;farseerfc@archlinux.org&apos;
paru -Sy archlinuxcn-keyring
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;（拍桌）&lt;strong&gt;重要操作！&lt;/strong&gt; 这一步相当于给软件源上一把锁，不做的话后面装软件会报错到怀疑人生～&lt;/p&gt;
&lt;h3&gt;3. 使用国内镜像加速&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 设置镜像源
echo &apos;Server = https://mirrors.jxust.edu.cn/archlinux/$repo/os/$arch&apos; | sudo tee /etc/pacman.d/mirrorlist
echo &apos;Server = https://mirrors.163.com/archlinux/$repo/os/$arch&apos; | sudo tee -a /etc/pacman.d/mirrorlist

# 刷新软件包数据库
paru -Syy
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4. 安装GNOME桌面环境、中文输入法和常用软件&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;paru -Sy --needed xorg gnome gnome-tweaks ptyxis gnome-nettool gnome-usage adwaita-icon-theme xdg-user-dirs-gtk fwupd gdm ibus ibus-libpinyin qt5ct qt6ct wps-office wps-office-fonts ttf-wps-win10 waterfox-bin vlc wqy-microhei adw-gtk-theme # 其中waterfox、wps-office、wps-office-fonts和ttf-wps-win10是AUR软件，这里我们用bin是为了加快安装速度；注意wps-office、wps-office-fonts和ttf-wps-win10没有bin
paru -R epiphany # 顺便淦掉GNOME自带的难用的浏览器
echo &apos;export QT_QPA_PLATFORMTHEME=qt5ct&apos; | tee -a ~/.xprofile | tee -a ~/.profile | tee -a ~/.bashrc # 设置Qt优化工具
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5. 字体缓存重建&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;sudo fc-cache -fv
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;6. 启用显示管理器并重启&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;sudo systemctl enable gdm
sudo reboot
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;🎉 四、大功告成&lt;/h2&gt;
&lt;p&gt;恭喜你！现在可以享受你的Arch Linux系统啦！(ﾉ◕ヮ◕)ﾉ*:･ﾟ✧&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;小提示：&lt;/strong&gt; 第一次进入GNOME桌面时，别忘了点击&quot;进行导览&quot;看看新手教程哦～&lt;br /&gt;
&lt;strong&gt;配置输入法：&lt;/strong&gt; 打开GNOME设置 → 键盘 → 添加输入源 → 中文 → 汉语（智能拼音） → 将“汉语（智能拼音）”放在第一位&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;🔙 五、Snapper使用教程&lt;/h2&gt;
&lt;h3&gt;1. Snapper是什么？&lt;/h3&gt;
&lt;p&gt;Snapper是一款用于Linux系统的系统备份和恢复工具 ，它能创建系统快照，就像给系统拍了一张张“照片”。在系统出现问题时（比如软件冲突导致无法启动、错误配置影响使用等情况），能将系统恢复到之前正常的状态。因其出色的备份与恢复能力，在Arch Linux堪称“必装软件”！&lt;br /&gt;
反而隔壁Timeshift，Rsync很慢，Btrfs有bug！不信请看VCR：\&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;真实案例1：&lt;/strong&gt; 原作者曾在Ta的March7th Ace 41.2实体机备份系统后使用&lt;code&gt;sudo dnf upgrade --refresh&lt;/code&gt;进行系统更新，结果Ta的AMD显卡驱动炸了！因为Ta在安装March7th Ace 41.2时使用了ext4文件系统，只能使用Timeshift Rsync。Ta尝试恢复备份，结果因为Ta的系统有一堆零碎文件，导致不管是备份还是恢复都很慢！&lt;br /&gt;
&lt;strong&gt;Moieo的调侃：&lt;/strong&gt; “你当时就应该用Snapper！现在怎么办？&lt;strong&gt;凉拌！&lt;/strong&gt; ”（拿起Fedora 42 Live USB疯狂暗示原作者）&lt;br /&gt;
&lt;strong&gt;真实案例2：&lt;/strong&gt; 原作者不信邪，使用Btrfs子卷模式重装March7th Vista 42.1后尝试立即使用Timeshift Btrfs备份，备份很快，但到了关键时候就掉链子了！Ta继续尝试更新系统，重启后还是一样：AMD显卡驱动炸了！于是，Ta尝试恢复之前的备份，结果！重启后，系统屡次Kernel Panic！于是，Ta就只好重装March7th Vista 42.3，并和Ta的数据说拜拜咯！&lt;br /&gt;
&lt;strong&gt;群友3595258138的回复：&lt;/strong&gt; timeshift不适用于Btrfs，强行使用可能会导致还原出错系统崩溃，Btrfs可考虑使用opensuse的snapper&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;2. 如何使用Snapper？&lt;/h3&gt;
&lt;p&gt;详见 &lt;a href=&quot;https://wiki.archlinuxcn.org/wiki/Snapper&quot;&gt;Snapper - Arch Linux 中文维基&lt;/a&gt;。&lt;/p&gt;
&lt;h2&gt;❓ 六、Q&amp;amp;A&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Q：不添加archlinuxcn密钥会怎么样？&lt;/strong&gt; &lt;br /&gt;
A：会收到“签名无效”警告，无法安装paru、中文输入法、微信等archlinuxcn源软件，然后只能重装系统💥&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Q：&lt;code&gt;sudo&lt;/code&gt;和&lt;code&gt;doas&lt;/code&gt;我该用哪个？&lt;/strong&gt; &lt;br /&gt;
A：优先使用&lt;code&gt;sudo&lt;/code&gt;。如果你的&lt;code&gt;sudo&lt;/code&gt;坏了（如“即使密码输入正确，也提示验证失败”），则使用&lt;code&gt;doas&lt;/code&gt;。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Q：为什么在tty下输入其他命令前还需要执行&lt;code&gt;LANG=C&lt;/code&gt;？&lt;/strong&gt; &lt;br /&gt;
A：这可不是什么“仪式感”！因为tty无法显示中文！执行后，该终端执行的命令会以英文输出。（当然这不会影响桌面环境下的终端，因此你每次进tty都得执行一遍这个）&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Q：为什么推荐使用&lt;code&gt;paru&lt;/code&gt;进行所有软件包操作，而不是使用&lt;code&gt;pacman&lt;/code&gt;和&lt;code&gt;yay&lt;/code&gt;？&lt;/strong&gt; &lt;br /&gt;
A：&lt;code&gt;paru&lt;/code&gt;是一个新晋AUR助手。它有一个很NB的点，那就是：&lt;code&gt;paru&lt;/code&gt;支持无缝对接&lt;code&gt;pacman&lt;/code&gt;，这一点&lt;code&gt;yay&lt;/code&gt;干不到！通过&lt;code&gt;paru&lt;/code&gt;，你就能像使用&lt;code&gt;pacman&lt;/code&gt;那样，一键搜索官方源和AUR软件！（前面甚至都不用加&lt;code&gt;sudo&lt;/code&gt;/&lt;code&gt;doas&lt;/code&gt;，少打5个字符！）&lt;br /&gt;
当然，你也可以为了方便，在安装完成后，这么干！&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;echo &apos;alias yay=paru&apos; &amp;gt;&amp;gt; ~/.bashrc
echo &apos;alias pacman=paru&apos; &amp;gt;&amp;gt; ~/.bashrc
sudo -i # 好人干到底！！！
echo &apos;alias yay=paru&apos; &amp;gt;&amp;gt; ~/.bashrc
echo &apos;alias pacman=paru&apos; &amp;gt;&amp;gt; ~/.bashrc
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果你用的&lt;code&gt;zsh&lt;/code&gt;，那你就这么干！&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;echo &apos;alias yay=paru&apos; &amp;gt;&amp;gt; ~/.zshrc
echo &apos;alias pacman=paru&apos; &amp;gt;&amp;gt; ~/.zshrc
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;温馨提示：别他妈手欠把&lt;code&gt;paru&lt;/code&gt;扬了，到时候你只能暂时&lt;code&gt;unalias&lt;/code&gt;把&lt;code&gt;paru&lt;/code&gt;用&lt;code&gt;pacman&lt;/code&gt;弄回来！&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Q：为啥我创建快照时提示「空间不足」？&lt;/strong&gt; &lt;br /&gt;
A：检查一下&lt;code&gt;/.snapshots&lt;/code&gt;目录！&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Btrfs 快照会共享文件数据，但子卷本身需要预留空间&lt;/li&gt;
&lt;li&gt;如果你往系统里塞了 100 个 G 的原神缓存，快照空间当然会爆啊！（ &lt;code&gt;du -sh /var/cache/paru&lt;/code&gt;自己查！）&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Q：Btrfs 快照真的比 Rsync 快 100 倍？&lt;/strong&gt; &lt;br /&gt;
A：实测数据说话：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Rsync 备份 20GB 系统：23 分钟（零碎文件让它像蜗牛）&lt;/li&gt;
&lt;li&gt;Btrfs 快照：0.3 秒（写时复制直接“克隆”元数据）&lt;br /&gt;
&lt;em&gt;（这就是为什么我宁愿花 1 小时研究 Btrfs，也不愿再等 Rsync 龟速备份）&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Q：不小心把重要快照扬了，还能抢救吗？&lt;/strong&gt; &lt;br /&gt;
A：节哀顺变…&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Btrfs快照删除后默认直接释放空间，不像Rsync有“保留版本”机制&lt;/li&gt;
&lt;li&gt;下次记得定期检查快照列表（&lt;code&gt;btrfs subvolume list /.snapshots&lt;/code&gt;），&lt;strong&gt;别他妈手滑点“删除”！&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Q：能不能用 Snapper 备份 Windows 分区？&lt;/strong&gt; &lt;br /&gt;
A：你在想屁吃！&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Timeshift 只认 Btrfs&lt;/li&gt;
&lt;li&gt;Windows 的 NTFS 分区？建议用&lt;code&gt;winsync&lt;/code&gt;或者直接买移动硬盘拷贝！&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Q：教程里说「Snapper 是 Arch 必装」，真的不是广告吗？&lt;/strong&gt; &lt;br /&gt;
A：当然不是！&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;除非 openSUSE 给我打钱（但他们开源项目穷得连服务器都靠爱发电）&lt;/li&gt;
&lt;li&gt;装不装随你，但等你误扬&lt;code&gt;/usr&lt;/code&gt;又没快照时，别他妈来论坛哭唧唧！&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Q：能不能在快照期间强制关机？&lt;/strong&gt; &lt;br /&gt;
A：你想炸系统啊？！&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Btrfs 快照创建时正在记录元数据，强制关机可能导致文件系统损坏&lt;/li&gt;
&lt;li&gt;正确做法：等快照完成，或者先喝杯咖啡再关机～&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Q：系统卡顿/风扇狂转怎么办？&lt;/strong&gt; &lt;br /&gt;
A：先查这！&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;打开终端输入 &lt;code&gt;htop&lt;/code&gt; → 找出占用资源的进程（可能是&lt;code&gt;paru&lt;/code&gt;编译AUR包）&lt;/li&gt;
&lt;li&gt;笔记本用户：安装并启用&lt;code&gt;power-profiles-daemon&lt;/code&gt;优化电池管理：&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;paru -S power-profiles-daemon
sudo systemctl enable power-profiles-daemon.service 
sudo systemctl start power-profiles-daemon.service
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;桌面环境：GNOME默认后台服务较多，可禁用不必要的扩展&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Q：SSD寿命会被Btrfs淦爆吗？&lt;/strong&gt; &lt;br /&gt;
A：想多了！&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Btrfs自带TRIM支持（默认启用）&lt;/li&gt;
&lt;li&gt;日常使用下，512GB SSD撑10年没问题（除非你拿它当硬盘录像机）&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Q：Steam游戏卡顿/闪退？&lt;/strong&gt; &lt;br /&gt;
A：兼容模式欢迎你！&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 安装Steam Play
paru -S steam-native-runtime proton-ge-custom
# 右键游戏 → 属性 → Steam Play → 勾选“启用非Steam游戏兼容层”
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Q：如何优雅地截图？&lt;/strong&gt; &lt;br /&gt;
A：按下&lt;code&gt;Print Screen&lt;/code&gt;键，直接进入GNOME Screenshot！&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Q：能Arch上安装Windows软件吗？&lt;/strong&gt; &lt;br /&gt;
A：当然能！
简单程序：用&lt;code&gt;wine&lt;/code&gt;！（&lt;code&gt;paru -S wine-staging&lt;/code&gt;）
复杂软件：装虚拟机！（Virtualbox/VMware）&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Q：误删&lt;code&gt;/usr&lt;/code&gt;了怎么办？&lt;/strong&gt; &lt;br /&gt;
A：凉拌炒鸡蛋，好吃又好看！&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;reboot &amp;amp;&amp;amp; sudo pacman -S arch-install-scripts  # 重装吧，少年
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;开玩笑的。。。如果你之前有Snapper备份，还可以抢救一下（Snapper没备份过你就重装吧老弟）&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Q：Arch能用来办公吗？&lt;/strong&gt; &lt;br /&gt;
A：不仅能！还能摸鱼！&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;办公：LibreOffice&lt;/li&gt;
&lt;li&gt;摸鱼：
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://ys.mihoyo.com/cloud&quot;&gt;原神，启动！&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://sr.mihoyo.com/cloud&quot;&gt;崩铁，启动！&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Q：为什么我们选择Arch而不是Ubuntu？&lt;/strong&gt; &lt;br /&gt;
A：因为我们追求：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;滚动更新带来的新鲜感&lt;/li&gt;
&lt;li&gt;自己配置系统的掌控感&lt;/li&gt;
&lt;li&gt;向新手炫耀时的成就感😎&lt;br /&gt;
（Ubuntu：那我走？）&lt;br /&gt;
以及......&lt;/li&gt;
&lt;li&gt;不被Snap限制的自由感！&lt;br /&gt;
（Ubuntu：Snap多好用啊）&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Q：Arch难吗？&lt;/strong&gt; &lt;br /&gt;
A：那必须的！但学会后：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;装Windows系统像过家家&lt;/li&gt;
&lt;li&gt;看其他Linux文档像读小学课本&lt;/li&gt;
&lt;li&gt;从此告别“电脑小白”称号🏆&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Q：其他问题？&lt;/strong&gt; &lt;br /&gt;
A：&lt;a href=&quot;https://wiki.archlinuxcn.org&quot;&gt;Arch Linux 中文维基&lt;/a&gt; 里面请&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Q：中文Wiki没写？&lt;/strong&gt; &lt;br /&gt;
A：出门右拐 &lt;a href=&quot;https://wiki.archlinux.org&quot;&gt;Arch Linux Wiki&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Q：英文Wiki也没写？&lt;/strong&gt; &lt;br /&gt;
A：（拍桌）大侠且慢！此处藏着30万Arch玩家，再难的坑也能给你盘出花来：&lt;a href=&quot;https://bbs.archlinuxcn.org&quot;&gt;Arch Linux 中文论坛&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Q：为什么这个教程天天在更新？&lt;/strong&gt; &lt;br /&gt;
A：原作者要么就是为了语言表述更准确，要么就是因为你们的建议要更新教程，&lt;s&gt;以及呼应Arch Linux滚动更新&lt;/s&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Q：当前教程版本号？&lt;/strong&gt;
A：北京时间 2025年8月3日 20:00:00&lt;/p&gt;
&lt;/blockquote&gt;
</content:encoded></item><item><title>ArchLinux Plasma 6 开启Samba服务（文件共享）</title><link>https://memo.moieo.net/2025/04/24/220548/</link><guid isPermaLink="true">https://memo.moieo.net/2025/04/24/220548/</guid><pubDate>Thu, 24 Apr 2025 14:05:48 GMT</pubDate><content:encoded>&lt;p&gt;在 Plasma 6 中的 Dolphin 使用文件共享&lt;/p&gt;
&lt;h2&gt;安装相关的插件&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;pacman -Sy kdenetwork-filesharing
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;编辑 Samba 配置文件&lt;/h2&gt;
&lt;p&gt;文件路径 &lt;code&gt;/etc/samba/smb.conf&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[global]  
 usershare path = /var/lib/samba/usershares  
 usershare max shares = 100  
 # usershare allow guests = yes  
 usershare owner only = no  
 workgroup = WORKGROUP  
 security = user  
 passdb backend = smbpasswd  
 name resolve order = lmhosts bcast host wins  
 unix charset = UTF-8  
 load printers = no  
 printing = bsd  
 printcap name = /dev/null  
 disable spoolss = yes  
 show add printer wizard = no  
 server string = Samba Server  
 log file = /var/log/samba/log.%m  
 # Put a capping on the size of the log files (in Kb).  
 max log size = 50  
 dns proxy = no  
#============================ Share Definitions ==============================  
#    
#[homes]    
# 启用这个块会默认共享对应用户的home目录
#  comment = Home Directories  
#  browsable = no  
#  writable = yes
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;配置用户组和文件夹&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;mkdir /var/lib/samba/usershares
groupadd fileshare
usermod -a -G fileshare $(whoami)
chown root:fileshare /var/lib/samba/usershares
chmod 1771 /var/lib/samba/usershares
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;启动 Samba 服务&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;systemctl restart smb nmb
systemctl enable smb nmb
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;将Linux用户添加到Samba数据库&lt;/h2&gt;
&lt;p&gt;这一步可以为Samba用户设置独立的密码&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;smbpasswd -a $(whoami)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;重启&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;reboot
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>ArchLinux安装过程</title><link>https://memo.moieo.net/2025/04/23/152137/</link><guid isPermaLink="true">https://memo.moieo.net/2025/04/23/152137/</guid><pubDate>Wed, 23 Apr 2025 07:21:37 GMT</pubDate><content:encoded>&lt;h2&gt;连接网络&lt;/h2&gt;
&lt;p&gt;插入有线连接再启动ISO就行了，不深究
使用&lt;code&gt;ping t.cn&lt;/code&gt; 能通就行了&lt;/p&gt;
&lt;h2&gt;更新系统时钟&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;timedatectl set-ntp true
# 将系统时间与网络时间进行同步
timedatectl status
# 检查服务状态
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;更换镜像&lt;/h2&gt;
&lt;p&gt;要换镜像网上搜去，这里不提供！&lt;/p&gt;
&lt;h2&gt;分区&lt;/h2&gt;
&lt;p&gt;使用fdisk工具进行分区操作
我这里使用的是&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;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;/&lt;/td&gt;
&lt;td&gt;500GiB&lt;/td&gt;
&lt;td&gt;/dev/nvme0n1p7&lt;/td&gt;
&lt;td&gt;根目录（系统装在这个分区里）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;/boot&lt;/td&gt;
&lt;td&gt;1Gib&lt;/td&gt;
&lt;td&gt;/dev/nvme0n1p6&lt;/td&gt;
&lt;td&gt;引导分区&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;/boot/efi&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;/dev/nvme0n1p1&lt;/td&gt;
&lt;td&gt;与Windows共用&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;格式化&lt;/h2&gt;
&lt;p&gt;将创建好的分区进行格式化，这里使用&lt;code&gt;btrfs&lt;/code&gt;格式的根目录分区
&lt;code&gt;btrfs&lt;/code&gt; 格式的分区可以使用 &lt;code&gt;zstd&lt;/code&gt; 进行压缩，支持快照功能&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mkfs.btrfs -f /dev/nvme0n1p7
mkfs.ext4 /dev/nvme0n1p6
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;挂载分区&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 挂载根目录分区 (我是不是应该创建子卷更好，毕竟我已经用btrfs了都)
mount -t btrfs -o compress=zstd:5 /dev/nvme0n1p7 /mnt
# 创建引导分区挂载需要的文件夹
mkdir /mnt/boot
# 挂载引导分区
mount -t ext4 /dev/nvme0n1p6 /mnt/boot
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;安装系统基础软件&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;pacstrap /mnt base base-devel linux linux-firmware btrfs-progs networkmanager neovim sudo bash bash-completion grub efibootmgr os-prober
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;生成 fstab 文件&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;fstab&lt;/code&gt; 用来定义磁盘分区。它是 Linux 系统中重要的文件之一。使用 &lt;code&gt;genfstab&lt;/code&gt; 自动根据当前挂载情况生成并写入 &lt;code&gt;fstab&lt;/code&gt; 文件&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;genfstab -U /mnt &amp;gt; /mnt/etc/fstab
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;复查一下 &lt;code&gt;/mnt/etc/fstab&lt;/code&gt; 确保没有错误&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cat /mnt/etc/fstab
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;切换到系统中&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;arch_chroot /mnt
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;修改时区&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;🍧 碎碎念
不要找北京啦！这里没有北京，只有上海啦！🚀&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;硬件时间设置&lt;/h2&gt;
&lt;p&gt;将系统时间同步到硬件时间&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;hwclock --systohc
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;修改语言&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;vim /etc/locale.gen
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;将&lt;code&gt;en_US.UTF-8&lt;/code&gt;和&lt;code&gt;zh_CN.UTF-8&lt;/code&gt;解除注释，然后用以下命令生成&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;locale-gen
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;需要添加相关的字体&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo pacman -S noto-fonts-cjk noto-fonts-emoji noto-fonts-extra
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;创建用户&lt;/h2&gt;
&lt;p&gt;如果需要安装plasma6桌面或者 GNOME 桌面，必须创建一个普通用户&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;useradd -G wheel [用户名]
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;安装 Grub&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=&quot;Arch Linux&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;生成Grub配置文件&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;grub-mkconfig -o /boot/grub/grub.cfg
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;安装 Plasma 6&lt;/h2&gt;
&lt;p&gt;蓝牙相关的，如果没有蓝牙可以省略
kde-applications 包含了KDE全家桶，不需要可以不装&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pacman -S plasma kde-applications sddm networkmanager bluez bluez-utils
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;需要启动相关的服务&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;systemctl enable sddm bluetooth NetworkManager
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;安装完成&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;exit # 退出 arch_chroot
umount -R /mnt
reboot
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;优化和问题解决&lt;/h2&gt;
&lt;h3&gt;电源管理&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;sudo pacman -S power-profiles-daemon
sudo systemctl start power-profiles-daemon.service
sudo systemctl enable power-profiles-daemon.service
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;解决回退的蜂鸣声&lt;/h3&gt;
&lt;p&gt;编辑 &lt;code&gt;/etc/modprobe.d/nobeep.conf&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;blacklist pcspkr
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;sddm中蓝牙自动连接&lt;/h3&gt;
&lt;p&gt;蓝牙被软锁了，但是暂时没发现其他解决方法，这样解决也可以
编辑 &lt;code&gt;/etc/udev/rules.d/99-rfkill-unblock-bluetooth.rules&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ACTION==&quot;add&quot;, SUBSYSTEM==&quot;bluetooth&quot;, KERNEL==&quot;hci0&quot;, RUN+=&quot;/usr/bin/rfkill unblock bluetooth&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;配置 AMD GPU&lt;/h3&gt;
&lt;p&gt;我用的是 AMD Radeon 780M 的集承显卡
修改 &lt;code&gt;/etc/mkinitcpio.conf&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;MODULES=(amdgpu radeon)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;再修改 &lt;code&gt;/etc/default/grub&lt;/code&gt; 中的 &lt;code&gt;GRUB_CMDLINE_LINUX_DEFAULT&lt;/code&gt; 加入 &lt;code&gt;radeon.cik_support=0 amdgpu.cik_support=1&lt;/code&gt;&lt;/p&gt;
</content:encoded></item><item><title>解决OpenOCD/串口在Linux中的权限问题</title><link>https://memo.moieo.net/2025/02/02/185312/</link><guid isPermaLink="true">https://memo.moieo.net/2025/02/02/185312/</guid><pubDate>Sun, 02 Feb 2025 10:53:12 GMT</pubDate><content:encoded>&lt;p&gt;问题说明：普通用户使用 OpenOCD 进行烧录时，无法访问USB设备，Arduino无法访问串口，每次使用 sudo 或者 pkexec 都需要输入密码，非常麻烦&lt;/p&gt;
&lt;h3&gt;解决方案&lt;/h3&gt;
&lt;p&gt;把 OpenOCD 的 &lt;code&gt;openocd/contrib/60-openocd.rules&lt;/code&gt; 复制到 &lt;code&gt;/etc/udev/rules.d/&lt;/code&gt; 文件夹中&lt;/p&gt;
&lt;h3&gt;串口的权限问题&lt;/h3&gt;
&lt;p&gt;编辑文件 &lt;code&gt;sudo vim /etc/udev/rules.d/70-ttyusb.rules&lt;/code&gt;
文件内容&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;KERNEL==&quot;ttyUSB[0-9]*&quot;, MODE=&quot;666&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;以上方案执行&lt;code&gt;sudo udevadm control --reload&lt;/code&gt;后生效&lt;/p&gt;
</content:encoded></item><item><title>Linux的GNOME中配置Minecraft游戏环境</title><link>https://memo.moieo.net/2025/01/30/200000/</link><guid isPermaLink="true">https://memo.moieo.net/2025/01/30/200000/</guid><pubDate>Thu, 30 Jan 2025 12:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;测试环境&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Linux: Fedora 41&lt;/li&gt;
&lt;li&gt;GNOME 47
HMCL 启动器：https://hmcl.huangyuhui.net/download/
&lt;img src=&quot;https://static.983577.xyz/images/2025/01/%E6%88%AA%E5%9B%BE%202025-01-30%2020-06-10.webp&quot; alt=&quot;HMCL&quot; /&gt;安装相关环境：&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;sudo dnf install java-21-openjdk openjfx
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;注意：Fedora 自带的 java-21-openjdk-handless 无法启动 HMCL&lt;/p&gt;
&lt;p&gt;需要在 Dash 栏显示软件名称的，需要编辑文件 &lt;code&gt;~/.local/share/applications/hmcl.desktop&lt;/code&gt;
内容：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Desktop Entry]
Encoding=UTF-8
Name=HMCL
GenericName=Hello Minecraft! Launcher
Comment=A launcher to start Minecraft
Exec=java -Dprism.forceGPU=true -jar /home/moieo/Minecraft/HMCL-3.6.11.jar
Icon=/home/moieo/Minecraft/.icon@8x.png
StartupWMClass=org.jackhuang.hmcl.Launcher
Terminal=false
Type=Application
Categories=Application;Game;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ICON 和 JAR 路径根据自己的情况修改
ICON 可以解压 JAR 包获取
如果使用了 Rounded Window Corners Reborn 圆角插件的，需要将插件排除包名&lt;code&gt;org.jackhuang.hmcl.Launcher&lt;/code&gt;，否则会有一个透明边框在外围&lt;/p&gt;
&lt;p&gt;字体使用 文泉驿，界面正常显示&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo dnf install wqy-bitmap-fonts -y
sudo dnf install wqy-unibit-fonts -y
sudo dnf install wqy-zenhei-fonts -y
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>ADC 采样 NTC 热敏电阻计算实际温度值</title><link>https://memo.moieo.net/2024/07/31/221520/</link><guid isPermaLink="true">https://memo.moieo.net/2024/07/31/221520/</guid><pubDate>Wed, 31 Jul 2024 14:15:20 GMT</pubDate><content:encoded>&lt;p&gt;通过 ADC 方式采样 NTC 热敏电阻 (10K)
得到 12 位采样数据（右对齐）&lt;/p&gt;
&lt;p&gt;通过 Steinhart-Hart 方程计算并得到温度计算公式
适用于 3.3v 基准电压，12 位宽 的情况&lt;/p&gt;
&lt;p&gt;转换公式如下&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#define to_temperature(adc_value) (1.0 / (0.001129148 + 0.000234185 * \
        log((10000 * adc_value * (3.3 / 4095.0)) / (3.3 - adc_value * \
        (3.3 / 4095.0))) + 0.0000000876741 * pow(log((10000 * adc_value * \
        (3.3 / 4095.0)) / (3.3 - adc_value * (3.3 / 4095.0))), 3))) - 273.15
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>STM32F103 实现 4x4 矩阵键盘的扫描</title><link>https://memo.moieo.net/2024/07/09/194457/</link><guid isPermaLink="true">https://memo.moieo.net/2024/07/09/194457/</guid><pubDate>Tue, 09 Jul 2024 11:44:57 GMT</pubDate><content:encoded>&lt;p&gt;直接放一个实物图在这里
&lt;img src=&quot;https://static.983577.xyz/images/2024/07/3245d42225334827b9cc81d5ccca889e.webp&quot; alt=&quot;实物图&quot; /&gt;&lt;/p&gt;
&lt;p&gt;接线放在这里~&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;STM32F103C8T6&lt;/th&gt;
&lt;th&gt;4x4&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;A0&lt;/td&gt;
&lt;td&gt;C4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A1&lt;/td&gt;
&lt;td&gt;C3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A2&lt;/td&gt;
&lt;td&gt;C2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A3&lt;/td&gt;
&lt;td&gt;C1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A4&lt;/td&gt;
&lt;td&gt;R1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A5&lt;/td&gt;
&lt;td&gt;R2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A6&lt;/td&gt;
&lt;td&gt;R3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A7&lt;/td&gt;
&lt;td&gt;R4&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;实现原理&lt;/h2&gt;
&lt;p&gt;遍历矩阵的每一行，开始时将当前遍历的行设置为 低电平，再扫描每一列并判断找出为低电平的列号，符合要求时记录行号和列号
结束当前行时再将当前行设置为 高电平&lt;/p&gt;
&lt;h2&gt;源代码&lt;/h2&gt;
&lt;p&gt;MATRIX_KEY_Sx 的编号由行号和列号组成
matrix_key.h&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#ifndef __MATRIX_KEY__
#define __MATRIX_KEY__

#include &amp;lt;stm32f10x.h&amp;gt;

#define ROW_PINS (GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7) // 定义行引脚为GPIOA的4、5、6、7
#define COL_PINS (GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3) // 定义列引脚为GPIOA的0、1、2、3

// 第1行
#define MATRIX_KEY_S1  0x18 // 0001 1000
#define MATRIX_KEY_S2  0x14 // 0001 0100
#define MATRIX_KEY_S3  0x12 // 0001 0010
#define MATRIX_KEY_S4  0x11 // 0001 0001
// 第2行
#define MATRIX_KEY_S5  0x28 // 0010 1000
#define MATRIX_KEY_S6  0x24 // 0010 0100
#define MATRIX_KEY_S7  0x22 // 0010 0010
#define MATRIX_KEY_S8  0x21 // 0010 0001
// 第3行
#define MATRIX_KEY_S9  0x48 // 0100 0100
#define MATRIX_KEY_S10 0x44 // 0100 0100
#define MATRIX_KEY_S11 0x42 // 0100 0010
#define MATRIX_KEY_S12 0x41 // 0100 0001
// 第4行
#define MATRIX_KEY_S13 0x88 // 1000 1000
#define MATRIX_KEY_S14 0x84 // 1000 0100
#define MATRIX_KEY_S15 0x82 // 1000 0010
#define MATRIX_KEY_S16 0x81 // 1000 0001

void Init_Matrix_Key(void);

void Scan_Matrix_Key(void (*Call_Back)(uint8_t));

#endif
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;matrix_key.c&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;stm32f10x.h&amp;gt;
#include &amp;lt;Delay.h&amp;gt;
#include &amp;lt;matrix_key.h&amp;gt;

void Init_Matrix_Key(void) {
  GPIO_InitTypeDef GPIO_InitStructure;

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // 使能GPIOA时钟

  // 设置行引脚为推挽输出
  GPIO_InitStructure.GPIO_Pin = ROW_PINS;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOA, &amp;amp;GPIO_InitStructure);

  // 设置列引脚为上拉输入
  GPIO_InitStructure.GPIO_Pin = COL_PINS;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  GPIO_Init(GPIOA, &amp;amp;GPIO_InitStructure);
}

void Scan_Matrix_Key(void (*Call_Back)(uint8_t)) {
  uint8_t row, col;
  uint8_t keyDetected = 0;

  for (row = 0; row &amp;lt; 4; row++) {                                  // 遍历行
    GPIO_ResetBits(GPIOA, 1 &amp;lt;&amp;lt; (row + 4)); 						   // 将当前行置为低电平，注意这里使用1 &amp;lt;&amp;lt; (row + 4)来选中行
    Delay_us(10);                                                  // 短暂延时以稳定电平

    for (col = 0; col &amp;lt; 4; col++) {                                // 遍历列
      if (GPIO_ReadInputDataBit(GPIOA, 1 &amp;lt;&amp;lt; col) == Bit_RESET) {   // 判断该列是否为低电平
        Delay_ms(100);                                             // 延时去抖动
        if (GPIO_ReadInputDataBit(GPIOA, 1 &amp;lt;&amp;lt; col) == Bit_RESET) { // 再次检查，确认按键被按下
          keyDetected = (1 &amp;lt;&amp;lt; col) | (1 &amp;lt;&amp;lt; (row + 4));             // 记录按键位置
          Call_Back(keyDetected);
          break;                                                   // 跳出列循环，因为同一时间只能有一个按键被按下
        }
        while(GPIO_ReadInputDataBit(GPIOA, 1 &amp;lt;&amp;lt; col) == Bit_RESET);// 等待弹起
      }
    }
    GPIO_SetBits(GPIOA, 1 &amp;lt;&amp;lt; (row + 4));                           // 恢复该行至高电平
    if (keyDetected) {
      break;                                                       // 如果检测到按键，跳出行循环
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在 main 中调用&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;void Matrix_Key_Callback(uint8_t key) {
  switch(key) {
    case MATRIX_KEY_S1:
      // TODO
      break;
  }
}

int main(void) {
  Init_Matrix_Key(); // 初始化	
  while (1) {
    Scan_Matrix_Key(Matrix_Key_Callback);
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;你可以在串口中输出按键的号码~
&lt;img src=&quot;https://static.983577.xyz/images/2024/07/7c4903ae63a846dca34dc7893791d37a.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;https://static.983577.xyz/images/2024/07/61501ec30a0e412cbbd570756b0c1f85.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>除了 VuePress，还有哪些文档工具值得推荐？</title><link>https://memo.moieo.net/2024/02/04/171624/</link><guid isPermaLink="true">https://memo.moieo.net/2024/02/04/171624/</guid><description>目前有多款文档工具可供选择，包括 VuePress、Docsify、Docusaurus、MkDocs 等。</description><pubDate>Sun, 04 Feb 2024 09:16:24 GMT</pubDate><content:encoded>&lt;h2&gt;为什么要使用文档生成工具？&lt;/h2&gt;
&lt;p&gt;使用文档工具可以快速生成文档的静态网站，节省非常多的时间，提高效率，一致性以易于维护和分发&lt;/p&gt;
&lt;blockquote&gt;
&lt;ol&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;/ol&gt;
&lt;/blockquote&gt;
&lt;p&gt;首先说说 VuePress 吧&lt;/p&gt;
&lt;h2&gt;VuePress&lt;/h2&gt;
&lt;p&gt;VuePress 是一个基于 Vue 的静态网站生成器。它使用 Markdown 来编写文档，并使用 Vue 来渲染文档内容&lt;/p&gt;
&lt;h3&gt;优点&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;高度可定制&lt;/strong&gt;：基于 Vue.js，可以非常灵活地定制文档界面和功能&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;性能优异&lt;/strong&gt;：利用 Vue 的单页应用特性，提供良好的页面加载性能和用户体验&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SEO 友好&lt;/strong&gt;：默认集成了 SEO 优化功能&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Markdown 支持&lt;/strong&gt;：良好的 Markdown 支持，易于编写文档&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;缺点&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;学习曲线&lt;/strong&gt;：对于不熟悉 Vue.js 的用户来说，可能需要一定的学习成本。&lt;/li&gt;
&lt;li&gt;**复杂配置：**对于高级功能，配置可能相对复杂。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Docusaurus&lt;/h2&gt;
&lt;p&gt;Docusaurus 是一个简洁且强大的静态站点生成器，适用于快速构建和维护项目文档、博客和技术宣传页面。由Meta（前身为Facebook）开源，它利用React技术栈，使得用户能够以Markdown格式轻松编写和组织内容。&lt;/p&gt;
&lt;h3&gt;优点&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;易于配置&lt;/strong&gt;：配置简单，易于上手。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Markdown 支持&lt;/strong&gt;：支持 Markdown，编写文档方便。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;主题丰富&lt;/strong&gt;：提供多个美观的主题供选择。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;社区支持&lt;/strong&gt;：由 Facebook 支持，社区活跃。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;缺点&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;功能相对有限&lt;/strong&gt;：相比于 VuePress，高级功能可能不足。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;性能&lt;/strong&gt;：相比于 VuePress，页面加载速度可能较慢。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;MkDocs&lt;/h2&gt;
&lt;p&gt;MkDocs 是一个轻量级的静态网站生成器，专为编写和发布项目文档而设计。它允许用户使用简单的 Markdown 语言来撰写文档，并通过 MkDocs 的构建命令将这些 Markdown 文件转换成结构化的、美观的 HTML 静态网页。&lt;/p&gt;
&lt;h3&gt;优点&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;简单易用&lt;/strong&gt;：安装和配置简单，适合初学者。&lt;/li&gt;
&lt;li&gt;** Markdown 友好**：对 Markdown 的支持很好，编写文档轻松。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;可定制性&lt;/strong&gt;：可以通过自定义 CSS 和模板进行一定程度的定制。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;插件系统&lt;/strong&gt;：有一套可用的插件，可以扩展功能。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;缺点&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;自定义能力有限&lt;/strong&gt;：相对于 VuePress，复杂的自定义可能难以实现。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;插件生态较小&lt;/strong&gt;：相比于 VuePress，插件数量和功能有限。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;mdBook&lt;/h2&gt;
&lt;p&gt;mdBook 是一个用 Rust 语言编写的开源命令行工具，用于从 Markdown 文件创建和管理在线书籍、文档集或教程。它提供了一个结构化的环境来组织和构建包含章节、副标题以及可选的自定义导航和样式表等内容的电子书或文档项目。&lt;/p&gt;
&lt;p&gt;这个工具只适合做一本书或文档，不适合多个文档的集合。&lt;/p&gt;
&lt;p&gt;看起来比较不错，如果你用它来编写 Rust 相关的文档，可以生成一个直接调用官方的接口，直接在网页中执行 Rust 代码片段。&lt;/p&gt;
&lt;h3&gt;优点&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;性能优异&lt;/strong&gt;：使用 Rust 编写，加载速度快，性能稳定。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Markdown&lt;/strong&gt; 原生支持：编写文档简单直观，格式化自然。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;简洁专注&lt;/strong&gt;：设计简单，专注于Markdown文档生成，没有多余的复杂功能&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;多平台支持&lt;/strong&gt;：支持多种操作系统，方便使用。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;缺点&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;功能相对有限&lt;/strong&gt;：相比于其他工具，可能缺乏一些高级功能和交互性。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;插件生态较小&lt;/strong&gt;：插件数量和功能有限，可能无法满足所有需求。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;社区支持&lt;/strong&gt;：虽然社区活跃，但规模不如 VuePress 和 Docusaurus。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>使用 Caddy 部署 Vue 等单页面Web应用</title><link>https://memo.moieo.net/2023/01/25/161921/</link><guid isPermaLink="true">https://memo.moieo.net/2023/01/25/161921/</guid><pubDate>Wed, 25 Jan 2023 08:19:21 GMT</pubDate><content:encoded>&lt;h1&gt;安装 Caddy&lt;/h1&gt;
&lt;p&gt;Caddy 是一个 Go 语言编写的开源 HTTP 服务器&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Caddy 有下面这些开箱即用的特性:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;全自动支持 HTTP/2 协议，无需任何配置。&lt;/li&gt;
&lt;li&gt;Caddy 使用 Let’s Encrypt 让你的站点全自动变成 HTTPS，无需任何配置。&lt;/li&gt;
&lt;li&gt;合理使用多核多核 得益于 go 的特性&lt;/li&gt;
&lt;li&gt;完全支持 IPv6 环境&lt;/li&gt;
&lt;li&gt;Caddy 对 WebSockets 有很好的支持&lt;/li&gt;
&lt;li&gt;自动把 Markdown 转成 HTML&lt;/li&gt;
&lt;li&gt;Caddy 对 log 格式的定义很容易&lt;/li&gt;
&lt;li&gt;易于部署 得益于 go 的特性，caddy 只是一个小小的二进制文件，没有依赖，很好部署&lt;/li&gt;
&lt;li&gt;得益于 Go 的跨平台特性，Caddy 很容易的支持了三大主流系统：Windows、 Linux、Mac
来自 知乎 &lt;a href=&quot;https://zhuanlan.zhihu.com/p/144208057&quot;&gt;@shooter&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://caddyserver.com/&quot;&gt;Caddy 官网&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://caddyserver.com/download&quot;&gt;下载 Caddy&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;本文配置 均使用 &lt;code&gt;Caddyfile&lt;/code&gt; 文件&lt;/p&gt;
&lt;h1&gt;基本配置&lt;/h1&gt;
&lt;p&gt;HTTP + HTTPS&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;moieo.cn {
  root * /srv/http # 网站根目录
  file_serve # 启用文件系统
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;HTTP&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;http://moieo.cn {
  root * /srv/http # 网站根目录
  file_serve # 启用文件系统
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;反之只用 HTTPS&lt;/p&gt;
&lt;h1&gt;Vue 等单页面应用部署&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;moieo.cn {
  root * /srv/http # 网站的根目录
  encode gzip zstd # 开启 gzip

  route {
    # 找不到文件时 使用 index.html
    # 解决 history 路由模式 404 的问题
    try_files {path} /index.html
    file_server # 开启文件系统
  }

  # 处理日志
  log {
    output file /data/moieo.cn.log # 保存文件
    format console # 日志格式
    level INFO # 日志级别
  }
}

&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;开启 Caddy&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;./caddy start --config ./Caddyfile 
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;文档&lt;/h1&gt;
&lt;p&gt;&lt;a href=&quot;https://caddyserver.com/docs/&quot;&gt;Caddy 官方文档&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://caddy2.dengxiaolong.com/docs/&quot;&gt;Caddy 中文文档&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;中文文档访问速度快&lt;/p&gt;
</content:encoded></item><item><title>Vite+Vue使用外部CDN引用element-plus全家桶</title><link>https://memo.moieo.net/2022/08/05/230838/</link><guid isPermaLink="true">https://memo.moieo.net/2022/08/05/230838/</guid><pubDate>Fri, 05 Aug 2022 15:08:38 GMT</pubDate><content:encoded>&lt;p&gt;参考：&lt;a href=&quot;https://juejin.cn/post/6992027986383863838&quot;&gt;vue3+vite2增加element-plus的CDN链接打包构建&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;网上 Vite.js 的资料少，踩了不少坑
在掘金中找到一篇资料，但还是避免不了遇到了一些奇奇怪怪的问题&lt;/p&gt;
&lt;p&gt;我这边使用的 &lt;code&gt;vite-plugin-cdn-import&lt;/code&gt; 插件&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://static.983577.xyz/images/2022/08/Screenshot_2022-08-05-23-28-48-872_com.termux.webp&quot; alt=&quot;解决&quot; /&gt;&lt;/p&gt;
&lt;p&gt;编辑 &lt;code&gt;vite.config.ts&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import { Plugin as importToCDN } from &quot;vite-plugin-cdn-import&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;importToCDN({
  modules: [
    {
      name: &quot;vue&quot;,
      var: &quot;Vue&quot;,
      path: &quot;//unpkg.com/vue@next&quot;,
    },
    {
      name: &quot;vuex&quot;,
      var: &quot;Vuex&quot;,
      path: &quot;//unpkg.com/vuex@next&quot;,
    },
    {
      name: &quot;vue-class-component&quot;,
      var: &quot;VueClassComponent&quot;,
      path: &quot;//unpkg.com/vue-class-component@next&quot;,
    },
    {
      name: &quot;element-plus&quot;,
      var: &quot;ElementPlus&quot;,
      path: &quot;//unpkg.com/element-plus&quot;,
      css: &quot;//unpkg.com/element-plus/dist/index.css&quot;,
    },
  ],
}),
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;用原文中的方法会出现错误
原因参考：使用了pinia或其他依赖于vue的库&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/67a34ca36df04992a0af368cc34c322d~tplv-k3u1fbpfcp-zoom-1.awebp&quot; alt=&quot;报错&quot; /&gt;&lt;/p&gt;
&lt;p&gt;上面方式可解决&lt;/p&gt;
</content:encoded></item><item><title>SQLMap进行SQL注入测试</title><link>https://memo.moieo.net/2022/07/31/225935/</link><guid isPermaLink="true">https://memo.moieo.net/2022/07/31/225935/</guid><pubDate>Sun, 31 Jul 2022 14:59:35 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;提示： 仅供学习使用，严禁用于违法用途&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;介绍&lt;/h2&gt;
&lt;h3&gt;简介&lt;/h3&gt;
&lt;p&gt;SQLMap 是一个开源的渗透测试工具，可以用来自动化检测，利用SQL注入漏洞，获取数据库的权限。
它的检测引擎非常强大，针对不同类型的数据库有不同的方案和选项，获取数据库中存储的数据。&lt;/p&gt;
&lt;p&gt;目前支持 MySQL、Oracle、PostgreSQL、Microsoft SQL Server、Microsoft Access 等数据库&lt;/p&gt;
&lt;h3&gt;输出级别&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;0：只显示python错误以及严重的信息
1：同时显示基本信息和警告信息（默认）
2：同时显示debug信息
3：同时显示注入的payload
4：同时显示HTTP请求
5：同时显示HTTP响应头
6：同时显示HTTP响应页面&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;安装&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;注：安装SQLMap需要Python环境
{% link https://sqlmap.org SQLMap官网 %}&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;克隆仓库&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap
cd sqlmap
python sqlmap.py
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;你也可以将它配置到环境变量中，具体方法请上搜索引擎找
&lt;img src=&quot;https://static.983577.xyz/images/2022/08/Screenshot_2022-07-31-23-03-10-552_com.termux.webp&quot; alt=&quot;运行图&quot; /&gt;
我这边配置了环境变量，所以可直接执行&lt;/p&gt;
&lt;h2&gt;使用&lt;/h2&gt;
&lt;h3&gt;1. 检查是否存在注入&lt;/h3&gt;
&lt;p&gt;例如注入目标为：http://127.0.0.1:8080/?id=1
则命令如下&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;python sqlmap.py -u &quot;http://127.0.0.1:8080/?id=1&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;执行过程如下
&lt;img src=&quot;https://static.983577.xyz/images/2022/08/Screenshot_2022-08-02-17-42-02-095_com.termux.webp&quot; alt=&quot;执行过程&quot; /&gt;
执行完毕后，可看到数据库类型，如果服务器后端使用的是PHP语言，会显示PHP的版本
&lt;img src=&quot;https://static.983577.xyz/images/2022/08/Screenshot_2022-08-02-17-44-29-937-edit_com.termux.webp&quot; alt=&quot;执行完毕&quot; /&gt;
如图所示，数据库类型为 &lt;code&gt;MySQL&lt;/code&gt;
PHP版本为 &lt;code&gt;8.1.8&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;2. 查询当前用户下所有数据库&lt;/h3&gt;
&lt;p&gt;用途：该命令在确定网站存在SQL注入漏洞时，用于查询当前用户下的数据库&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;python sqlmap.py -u &quot;http://127.0.0.1:8080/?id=1&quot; --dbs
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://static.983577.xyz/images/2022/08/Screenshot_2022-08-02-18-17-26-936_com.termux.webp&quot; alt=&quot;所有数据库&quot; /&gt;
运行结束后可看到一些 数据库 的名称，它们将以&lt;code&gt;[*]&lt;/code&gt;开头
&lt;code&gt;--dbs&lt;/code&gt;参数缩写成&lt;code&gt;-D xxx&lt;/code&gt;，该参数为查询&lt;code&gt;xxx&lt;/code&gt;数据库下的内容&lt;/p&gt;
&lt;h3&gt;3. 获取数据库中的表名&lt;/h3&gt;
&lt;p&gt;用途：该命令在确定网站存在SQL注入漏洞时，可获取数据库下所有表的名称&lt;/p&gt;
&lt;p&gt;&lt;code&gt;-D&lt;/code&gt; 参数用来指定数据库，例如 &lt;code&gt;-D moieo&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;python sqlmap.py -u http://127.0.0.1:8080/?id=1 -D moieo --tables
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://static.983577.xyz/images/2022/08/Screenshot_2022-08-02-18-21-55-513_com.termux.webp&quot; alt=&quot;所有数据表&quot; /&gt;
运行结束后可看到所有数据表的名称，继续注入可使用 &lt;code&gt;-T&lt;/code&gt; 参数，该参数为 &lt;code&gt;--tables&lt;/code&gt;的缩写，用于指定数据表继续注入获取数据&lt;/p&gt;
&lt;h3&gt;4. 获取数据表的字段名&lt;/h3&gt;
&lt;p&gt;用途：在查询完表名后，指定数据库和数据表进行注入测试，获取该表下所有字段&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;python sqlmap.py -u http://127.0.0.1:8080/?id=1 -D moieo -T moieo_comments --columns
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://static.983577.xyz/images/2022/08/Screenshot_2022-08-02-18-28-17-588_com.termux.webp&quot; alt=&quot;所有字段&quot; /&gt;
运行结束后得到所有字段&lt;/p&gt;
&lt;h3&gt;5. 获取数据表内存储的数据&lt;/h3&gt;
&lt;p&gt;用途：在获取并确定数据表内有字段时使用，可获得数据表内存储的数据&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;python sqlmap.py -u http://127.0.0.1:8080/?id=1 -D moieo -T moieo_comments --dump
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://static.983577.xyz/images/2022/08/Screenshot_2022-08-02-18-32-38-680_com.termux.webp&quot; alt=&quot;表内的所有数据&quot; /&gt;
可以看到，执行结束后可获得数据表内每个字段的数据&lt;/p&gt;
&lt;h2&gt;其他选项&lt;/h2&gt;
&lt;h3&gt;1. 获取数据库所有用户&lt;/h3&gt;
&lt;p&gt;在有权管理所有用户的情况下 &lt;code&gt;--users&lt;/code&gt; 选项可获得数据库所有用户名&lt;/p&gt;
&lt;h3&gt;2. 获取数据库用户的密码&lt;/h3&gt;
&lt;p&gt;在有权管理所有用户的情况下 &lt;code&gt;--passwords&lt;/code&gt; 选项可获得所有用户的密码，该选项获得到的数据是经过哈希算法加密的
可以尝试使用 https://www.cmd5.com/ 硬解&lt;/p&gt;
&lt;h3&gt;3. 获取当前网站数据库的名称&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;--current-db&lt;/code&gt; 选项，可获得当前网站数据库的名称&lt;/p&gt;
&lt;h3&gt;4. 获取当前网站数据库使用的用户名称&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;--current-user&lt;/code&gt; 选项，用于获取当前用户名称&lt;/p&gt;
&lt;h3&gt;杂项&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;--is-dba&lt;/code&gt; 用于判断用户是否管理员权限&lt;/p&gt;
&lt;p&gt;&lt;code&gt;--roles&lt;/code&gt; 列出数据库管理员角色&lt;/p&gt;
&lt;p&gt;&lt;code&gt;--referer&lt;/code&gt;，当&lt;code&gt;--level&lt;/code&gt;的参数为3或以上，用于指定来源网站，欺骗目标网站，参数为URL&lt;/p&gt;
&lt;p&gt;&lt;code&gt;--sql-shell&lt;/code&gt; 运行自定义SQL语句&lt;/p&gt;
&lt;p&gt;&lt;code&gt;--os-cmd&lt;/code&gt; 或 &lt;code&gt;--os-shell&lt;/code&gt; 执行任意操作系统命令&lt;/p&gt;
&lt;p&gt;&lt;code&gt;--file-write xxx.php --file-dest xxx.php&lt;/code&gt; 上传文件到数据库服务器，前者为源文件路径，后者为目标数据库服务器的文件路径&lt;/p&gt;
&lt;p&gt;&lt;code&gt;--file-read&lt;/code&gt; 从数据库服务器中读取文件，参数为数据库服务器中的文件路径&lt;/p&gt;
</content:encoded></item><item><title>IP查询接口分享</title><link>https://memo.moieo.net/2022/07/23/115258/</link><guid isPermaLink="true">https://memo.moieo.net/2022/07/23/115258/</guid><pubDate>Sat, 23 Jul 2022 03:52:58 GMT</pubDate><content:encoded>&lt;h4&gt;阿里云&lt;/h4&gt;
&lt;p&gt;阿里云&lt;code&gt;ipip.net&lt;/code&gt;提供的 IP 查询接口&lt;/p&gt;
&lt;p&gt;接口地址：https://api.myip.la/cn?json
请求示例&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;curl https://api.myip.la/cn?json
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;响应结果&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;ip&quot;: &quot;172.104.94.100&quot;,
  &quot;location&quot;: {
    &quot;country_code&quot;: &quot;JP&quot;,
    &quot;country_name&quot;: &quot;日本&quot;,
    &quot;province&quot;: &quot;东京都&quot;,
    &quot;city&quot;: &quot;品川区&quot;,
    &quot;latitude&quot;: &quot;35.6130514&quot;,
    &quot;longitude&quot;: &quot;139.7344198&quot;
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;https://www.myip.la/&quot;&gt;详细文档&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;Moieo Api IP 查询接口&lt;/h4&gt;
&lt;p&gt;接口地址：GET https://api.moieo.net/ip/114.114.114.114
请求头&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;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;timestamp&lt;/td&gt;
&lt;td&gt;时间戳(ms)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;请求示例
例如 IP 为：114.114.114.114&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;curl -XGET -H &quot;timestamp: $(date +%s%3N)&quot; https://api.moieo.net/ip/114.114.114.114
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;响应结果&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;code&quot;: 200,
  &quot;msg&quot;: &quot;success&quot;,
  &quot;data&quot;: {
    &quot;ip&quot;: &quot;114.114.114.114&quot;,
    &quot;ip_number&quot;: 1920103026,
    &quot;location&quot;: &quot;江苏省南京市&quot;,
    &quot;net_service&quot;: &quot;南京信风网络科技有限公司GreatbitDNS服务器&quot;
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;数据来源于&lt;code&gt;纯真网络&lt;/code&gt;开源数据库&lt;/p&gt;
</content:encoded></item></channel></rss>