Blog/rss2.xml
2024-11-19 03:05:20 +00:00

510 lines
265 KiB
XML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:content="http://purl.org/rss/1.0/modules/content/">
<channel>
<title>Foxhole</title>
<link>https://blog.southfox.me/</link>
<atom:link href="https://blog.southfox.me/rss2.xml" rel="self" type="application/rss+xml"/>
<description></description>
<pubDate>Sun, 31 Dec 2023 21:32:20 GMT</pubDate>
<generator>http://hexo.io/</generator>
<item>
<title>2023 年终总结</title>
<link>https://blog.southfox.me/2023/12/2023%E5%B9%B4%E7%BB%88%E6%80%BB%E7%BB%93/</link>
<guid>https://blog.southfox.me/2023/12/2023%E5%B9%B4%E7%BB%88%E6%80%BB%E7%BB%93/</guid>
<pubDate>Sun, 31 Dec 2023 21:32:20 GMT</pubDate>
<description>&lt;p&gt;什么,已经要 2024 年了?!&lt;/p&gt;</description>
<content:encoded><![CDATA[<p>什么,已经要 2024 年了?!</p><span id="more"></span><h2 id="幸运"><a href="#幸运" class="headerlink" title="幸运"></a>幸运</h2><blockquote><p>And even when I might fall down,</p><p>I know my luck come back around.</p></blockquote><p>今年如果如果要选出一个关键词的话,那么就是「幸运」吧,每次找工都是海投简历快要绝望的时候「刚好」被「捞」到了。首先是三月份的实习,距离家的位置还算不远。作为一家还算大型的企业做事十分垂直,做的事多都是一些填表单之事,基本上很容易被替代。也「幸好」我有 <code>Emacs</code> ,在一大堆服务器上翻找工程文件里 blame 是谁提交的代码,在一大堆编译产物翻找定位时真得救了我的命。</p><p>这段时间就像是静止了一样:每天被闹钟逼迫着起床;然后走到附近的公交站(甚至因为这样和公交车司机混了个脸熟);半小时后下公交,然后走向大厦;等电梯(有时人太多也会选走楼梯);到工位打开电脑;工;下班后在等公交;座半小时公交; 车站下车然后回家。在一座小城找到一份对于当地人耳熟能详企业的工作,如果能一直这样下去也还算是不错吧。但因为 2023 年寒冬实在太冷,冷意已经让大多数企业都得凝住呼吸,生怕机体的热量散失。所以自然是没有什么位置留给新来者的,甚至同组的一位实习快一年的小哥都没有转正的机会,所以当时间一到,我就只好潇洒走人了。</p><p>然后七月到十月就待在家里,算是一个小小的 gap time 吧,可能这个情况会一直持续到明年,真是这样的话本篇博文可能就没有那么多内容,写到这里就应该写点什么明年展望就结笔了,但生活总是像个迷,并没有给我这种发展。</p><p>十一月还是打算「出洞」,打算呼吸点新鲜空气。但是就业市场寒冬更甚,简历比起三月份更加沉底(哪怕开启广域模式),而且临近年关,也没有什么公司打算在这时候招人,正当我已经打算放弃「回洞」时,没想到就正好 HIT 到一家了。一家「幸运」的在今年拉到投资逆流而上就正好在这时招兵买马的公司,刚好也觉得我「折腾」的一大堆东西也「不容易」所以就这么对上了。一切都是那么恰好,但就是工作地点离家超过两千公里,虽然地点当初是在招聘软件自己选的,真发生时却还是有点恍惚。就算临行前故作坚定但潜意识下估计也是一大堆思绪组成的乱麻吧,头次座飞机、一落地就要开始找中介寻找房子、在名宿和租房地点两头跑搬运整理东西、甚至为了一台炸了的服务器就这么修到凌晨三点,不敢相信报到当天我的黑眼圈该重到什么地步。不过如今我喝着热茶写出这些事也就代表一切都已落定。</p><h2 id="坚定"><a href="#坚定" class="headerlink" title="坚定"></a>坚定</h2><blockquote><p>好像大自然只支持一种理解能力,养活了四足动物就养不活禽鸟,养活了会爬的东西就养不活会飞的东西</p></blockquote><p>可能还有一件拖了很久的事「有幸」在三个月的 gap time 里想好了,那就是「坚定的自我认同」,虽然说之前的人生里一直知道这件事但是却一直没有调度它导致这个任务一直在挂起,不知道是真觉得还早还是因为一直被压抑了呢?</p><p>我作为在这跟熵的「无情之手」永恒对抗下的一个生命,从海底的那隆起的石塔中「逃脱」而出,花了几十亿年将自己的足迹散步到这个星球并永远地改变了这里且绝不停歇嗡嗡震动的玩意,到底意味着什么呢?或者「在十个当中只得一个」意味着什么呢?我想生命「幸好」不总是一样,允诺了在每次分裂复制时不同的空间,造就了生命的可塑性,或许就连作为其象征——链条底层结构都「改朝换代」了几次。</p><h2 id="展望"><a href="#展望" class="headerlink" title="展望"></a>展望</h2><p>作为「幸运」的一年,在年末找到了一份「幸运」的工作,也有时间一直做了之前一直想做的事,比如烘焙之类的,也体会到了「面多加水, 水多加面」是一件多窘迫的事。明年也没有什么特别的展望了,毕竟今年的多数事已经开始将我水豚化了,一些事情看起来很大很可怕但最后压到头上可能只是一个「橘子」,完全没有必要去付出超出的担忧。希望我明年能像我以为的这么处事不惊下去吧,不论是工作上的事、自己一个人潇洒待着抑或是打算走进一段亲密关系、不论「幸运」还是「没那么幸运」。</p>]]></content:encoded>
<category domain="https://blog.southfox.me/categories/%E9%9A%8F%E7%AC%94/">随笔</category>
<category domain="https://blog.southfox.me/tags/%E9%9A%8F%E7%AC%94/">随笔</category>
<category domain="https://blog.southfox.me/tags/%E5%B9%B4%E7%BB%88%E6%80%BB%E7%BB%93/">年终总结</category>
<comments>https://blog.southfox.me/2023/12/2023%E5%B9%B4%E7%BB%88%E6%80%BB%E7%BB%93/#disqus_thread</comments>
</item>
<item>
<title>如何杀死一个去中心化网络?</title>
<link>https://blog.southfox.me/2023/06/%E5%A6%82%E4%BD%95%E6%9D%80%E6%AD%BB%E4%B8%80%E4%B8%AA%E5%8E%BB%E4%B8%AD%E5%BF%83%E5%8C%96%E7%BD%91%E7%BB%9C%EF%BC%9F/</link>
<guid>https://blog.southfox.me/2023/06/%E5%A6%82%E4%BD%95%E6%9D%80%E6%AD%BB%E4%B8%80%E4%B8%AA%E5%8E%BB%E4%B8%AD%E5%BF%83%E5%8C%96%E7%BD%91%E7%BB%9C%EF%BC%9F/</guid>
<pubDate>Sat, 24 Jun 2023 14:03:55 GMT</pubDate>
<description>&lt;p&gt;例如联邦宇宙(&lt;code&gt;Fediverse&lt;/code&gt;)。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://media.southfox.me/ipfs/bafkreiht6bsh4u5ncv3ezxbkvyinkbhqxh6sjxfnsz2vw6lifnsa3jzllq&quot; alt=&quot;头图&quot;&gt;&lt;/p&gt;</description>
<content:encoded><![CDATA[<p>例如联邦宇宙(<code>Fediverse</code>)。</p><p><img src="https://media.southfox.me/ipfs/bafkreiht6bsh4u5ncv3ezxbkvyinkbhqxh6sjxfnsz2vw6lifnsa3jzllq" alt="头图"></p><span id="more"></span><blockquote><p>这篇文章是一篇翻译,原文为 <a href="https://ploum.net/2023-06-23-how-to-kill-decentralised-networks.html">How to Kill a Decentralised Network (such as the Fediverse) </a></p></blockquote><p>现在是 2023 年。整个互联网都在科技巨头的帝国掌握下吗?不,因为有一些小村落还在反抗这种趋势,其中一些村落开始聚集,形成「联邦宇宙」。</p><p>随着 Twitter 和 Reddit 上的发生的争论,联邦宇宙开始获得名气和注意,一些人开始在日常生活中使用。帝国开始注意到了。</p><h2 id="资本家反对竞争"><a href="#资本家反对竞争" class="headerlink" title="资本家反对竞争"></a>资本家反对竞争</h2><p>正如 Fecebook 著名投资人 Peter Thiel 所说:“竞争是对于失败者说的”。是的,对于那些总将「市场总是对的」挂在嘴边的人来说,身处市场中却并不想要市场,他们想要垄断。自成立以来, Facebook 一直非常小心地消灭竞争对手。最简单的办法就是收购每一个可能成为竞争对手的公司。例如 Instagram、WhatsApp 被收购只是因为产品吸引了用户的注意并有可能为 Fecebook 蒙上阴影。</p><p>但联邦宇宙是买不到的。联邦宇宙是一个不同服务器通过协议ActivityPub 进行连接的非正式组织informal group。这些服务器甚至运行着不同的软件Mastodon 是最著名的一个,但你也可以运行 Pleroma、Pixelfed、Peertube、WriteFreely、Lemmy 等)。</p><p>你无法买下一个去中心化网络!</p><p>但还有另外一种办法:让它变得无关紧要。这正是谷歌对 XMPP 所做的事。</p><h2 id="谷歌如何加入-XMPP-联盟"><a href="#谷歌如何加入-XMPP-联盟" class="headerlink" title="谷歌如何加入 XMPP 联盟"></a>谷歌如何加入 XMPP 联盟</h2><p>20 世纪末,即时通讯工具风头无限。第一个获得巨大成功的应用是 ICQ随后是 MSN 。 MSN 就类似于今天的 Tiktok :青少年可以在没有大人陪伴下在这个世界里度过数小时或数天的时间。</p><p>因为 MSN 是微软的一部分,谷歌希望与其竞争,并于 2005 年发布了 Google Talk并将其界面整合在 Gmail 里。请记住在那时还没有智能手机或是小体积的网页应用。应用程序必须安装在计算机上,所以 Gmail 的网页交互是开创性的。MSN 甚至在某个时间是和操作系统捆绑在一起的,很难将其卸载。与内置在操作系统的预装应用相比,在 Gmail 用网页进行构建的聊天是一种更贴近用户的方式。</p><p> 在谷歌和微软开始争夺霸权地位时自由极客们开始尝试构建去中心化的即时通信。就像电子邮件一样XMPP 是一种联邦协议多个服务器之间可以通过协议互相通信每个用户可以使用任意客户端与任意服务器上的任意用户进行通信。ActivityPub 和联邦宇宙也是这样运作的。</p><p>2006 年Google Talk 开始实现 XMPP 兼容,谷歌正在认真考虑 XMPP 协议。2008 年,当我正在工作时,我的手机响了。在电话里,有人告诉我:“嗨,我是谷歌,我们想雇佣你。”我们打了几个电话,他们是通过 XMPP 的开发者列表找到了我,并表示正在寻找 XMPP 服务器管理员。</p><p>所以谷歌确实在加入联盟,这有多酷?这意味着每个 Gmail 用户都可以变成 XMPP 用户。这只会对 XMPP 有好处,是吗?我高兴坏了。</p><h2 id="谷歌如何杀死-XMPP"><a href="#谷歌如何杀死-XMPP" class="headerlink" title="谷歌如何杀死 XMPP"></a>谷歌如何杀死 XMPP</h2><p>当然现实没有那么美好。首先,尽管制定了 XMPP 标准,谷歌仍然在实行着自己没有任何人审查的封闭实现。事实证明,他们并不总是尊重他们正在制定的协议。他们并没有完全实现所有标准,这迫使 XMPP 的降低速度以便适应。好的功能没有在 XMPP 客户端中实现或使用,因为它们与 Google Talk 不兼容(头像功能都花了非常久时间才在 XMPP 里实装)。联邦还总会被破坏:有时是几小时或数天,谷歌服务器和常规 XMPP 服务器之间无法进行通信。XMPP 社区成为了谷歌服务器的监管员和除错员,发布违规和停机信息(我做了好几次这种事,可能这就是为什么有这份工作的原因吧)。</p><p>而且由于 Google Talk 用户远多于「真正的 XMPP」用户因此「不关心 Google Talk 用户」的情况并不多。新人发现 XMPP 并不是 Google Talk 用户的经历让人非常沮丧,因为他们接触的大多数都是 Google Talk 用户。他们认为他们可以轻易的与 Google Talk 用户沟通,但这相当于他们在用 Google Talk 的基本版或是降级版本。典型的 XMPP 名单主要由 Google Talk 用户和一些极客组成。</p><p>在 2013 年,谷歌意识到大多数 XMPP 交互都是在 Google Talk 用户之间进行的。他们并不关心遵守没有百分之百掌握在他们手里的协议,所以他们中止了合作并宣布不进行结盟。并开始踏上一条即时通讯软件的漫长探索,从 Hangout 开始(随后是 Allo、Duo ,之后我就记不清了)。</p><p>正如预料一样,谷歌用户没有太多感受,事实上,他们什么也没意识到。最坏的情况是他们的一些联系人离线了,就这样。但对于 XMPP 联邦来说,相当于绝大多数用户凭空蒸发了一样。即使是最狂热的 XMPP 拥趸,也要创建一个谷歌帐号和朋友保持联系。请记住:对于他们来说,我们就是单纯离线了,这是我们的错。</p><p>虽然 XMPP 仍然是一个存在并且活跃的社区但它未从这次打击中恢复过来。对谷歌投入了过高的期待导致了巨大的失望然后就这么被遗忘了。XMPP 变得小众以至于群聊应用开始流行时Slack、Discord自由软件社区重新造了一个协议Matrix与之竞争但群聊已经可以通过 XMPP 实现了。(免责声明:我没有研究过 Matrix 协议,所以我不知道在技术层面上与 XMPP 相比如何。我只确信它解决了类似的问题并与 XMPP 在相同的空间上竞争。)</p><p>(译按: Matrix 和 XMPP 对比在 Matrix 官网 FAQ 上就有回答(虽然被标注为过时了):<a href="https://matrix.org/docs/legacy/faq/">What is the difference between Matrix and XMPP? - FAQ</a></p><p>如果谷歌未加入 XMPP 或从未被视为其中的一部分,今天的 XMPP 会有所不同吗没有人知道。但我相信它会成长的更慢可能更健康。它将比今天更大、更重要它将成为默认的去中心化通讯平台。但有一点是肯定的如果谷歌没有加入XMPP 不会比现在更糟糕。</p><h2 id="并不是首例:微软的心机"><a href="#并不是首例:微软的心机" class="headerlink" title="并不是首例:微软的心机"></a>并不是首例:微软的心机</h2><p>谷歌对 XMPP 做的事并不新鲜。事实上,在 1998 年,微软的工程师 Vinod Vallopllil 就明确写下了一篇「削弱 OSS (译按:开源软件)攻击」的文章,其中他建议「去商品化协议和应用程序……]通过拓展这些协议或是开发新协议,我们可以拒绝 OSS 项目进入市场。</p><p>随着 Windows 2000 的发布微软将这理论付诸实践Windows 2000 提供了对 Kerberos 安全协议的支持。但该协议得到了拓展。这些拓展规范可以免费下载,但必须要接受禁止实现这些拓展的许可证。一旦点击「确定」,你就无法使用 Kerberos 的任何开源版本。这么做的目标就是消灭任何与之竞争的网络项目例如 Samba 。</p><p>Glyn Moody 在他的著作《Rebel Code》中讲述了这一传闻并表明扼杀开源和去中心化项目是确有预谋的目标。它从来不是随机发生的也不是由什么坏运气导致的。</p><p>微软还采用了类似的策略,通过专有格式(文件格式可以被视为交换数据的协议)的 Microsoft Office 来确保在办公市场的主导地位。当替代方案OpenOffice 然后是 LibreOffice在处理 doc&#x2F;xls&#x2F;ppt 格式能力变得足够好时微软发布了一种他们称之为「开放和标准化」的新格式。格式故意弄得非常复杂20,000 页的规范!),而且最重要的是,它是错误的。是的,标准中引入了一些错误,这意味完整实现 OOXML 格式的软件的表现将与 Microsoft Office 不同。</p><p>这些错误以及政治游说是促使慕尼黑市恢复 Linux 迁移的原因之一。所以是的,这个策略运作良好。因为如今 docx、xlsx 和 pptx 仍然是标准格式。来源:我就在那里,由慕尼黑市间接支付费用,使 LibreOffice OOXML 的渲染更接近 Microsoft 的渲染,而不是遵循规范。</p><p>后按:这种策略有一个维基百科词条:</p><ul><li><p><a href="https://en.wikipedia.org/wiki/Embrace,_extend,_and_extinguish">Embrace, extend, and extinguish - wikipedia</a></p></li><li><p><a href="https://zh.wikipedia.org/wiki/%E6%8B%A5%E6%8A%B1%E3%80%81%E6%89%A9%E5%B1%95%E5%86%8D%E6%B6%88%E7%81%AD">拥抱、扩展再消灭 - 维基百科</a></p></li></ul><h2 id="Meta-和联邦宇宙"><a href="#Meta-和联邦宇宙" class="headerlink" title="Meta 和联邦宇宙"></a>Meta 和联邦宇宙</h2><p>不了解历史的人终究会重蹈覆辙,这就是现在 Meta 译按Facebook 的公司现在改名叫 Meta 了)和联邦宇宙发生的事。 </p><p>有传言称 Meta 会实现「联邦宇宙兼容」,这意味着你可以通过 Mastodon 账户关注 Instagram 上的人。</p><p>我不知道这些传言是真是假Meta 是否在考虑实现它。但我在 XMPP 和 OOXML 方面的经验告诉我一件事情,如果 Meta 加入联邦宇宙Meta 将是唯一的胜者。事实上现在的反应已经让他们开始赢了:联邦宇宙在阻止 Meta 与不阻止 Meta 之间存在分歧。如果继续发生这种情况,这将意味着一个支离破碎令人沮丧的俩半式联邦,对新来者而言没有什么吸引力。</p><p>后按:这些传言得到了证实,一位来自 fosstodon.org 的 Mastodon 管理员 kev 已被邀请参加和 Meta 的非正式会议。他做出了最好的选择:他礼貌地拒绝掉了,最重要的是,公开了该电子邮件以对其用户保持透明。谢谢 kev </p><ul><li><a href="https://fosstodon.org/@kev/110592625692688836">相关邮件截图和回复 - fosstodon.org</a></li></ul><p>我知道我们都梦想着让我们所有的朋友和家人进入到联邦宇宙上,这样我们就可以完全避免专有网络。但联邦宇宙并不寻求市场主导地位或是利润,联邦宇宙并不寻求增长。它提供了一个自由的场所。加入联邦宇宙的人都是那些寻求自由的人。如果人们还没有准备好或者并不追寻自由,那也没关系。他们有权留在专有平台上,我们不应该强迫他们进入联邦宇宙。我们不应该不惜一切代价试图容纳尽可能多的人。我们应该诚心诚意并确保人们加入联邦宇宙是因为他们想分享其背后的一些价值观。</p><p>在无脑增长、不惜一切代价的意识形态下与 Meta 竞争,我们肯定会失败。他们是这场比赛的大师,他们试图让每个人都进入他们的领域,让人们使用他们熟悉的武器与他们竞争。</p><p>联邦宇宙只能坚守阵地,通过谈论自由、道德、伦理和价值观来获胜。通过公开、非商业和非监听的方式讨论,承认目标不是去获胜。我们的目标是继续成为一个工具,一个致力于为互联网上的人类提供自由场所的工具。这是任何商业实体都不会提供的东西。</p><p><a href="https://framapiaf.org/@davidrevoy/110583258129951932">头图 by David Revoy</a></p>]]></content:encoded>
<category domain="https://blog.southfox.me/categories/%E9%9A%8F%E7%AC%94/">随笔</category>
<category domain="https://blog.southfox.me/tags/%E8%81%94%E9%82%A6%E5%AE%87%E5%AE%99/">联邦宇宙</category>
<category domain="https://blog.southfox.me/tags/%E7%BF%BB%E8%AF%91/">翻译</category>
<comments>https://blog.southfox.me/2023/06/%E5%A6%82%E4%BD%95%E6%9D%80%E6%AD%BB%E4%B8%80%E4%B8%AA%E5%8E%BB%E4%B8%AD%E5%BF%83%E5%8C%96%E7%BD%91%E7%BB%9C%EF%BC%9F/#disqus_thread</comments>
</item>
<item>
<title>GPG 浅尝辄止</title>
<link>https://blog.southfox.me/2023/06/GPG%20%E6%B5%85%E5%B0%9D%E8%BE%84%E6%AD%A2/</link>
<guid>https://blog.southfox.me/2023/06/GPG%20%E6%B5%85%E5%B0%9D%E8%BE%84%E6%AD%A2/</guid>
<pubDate>Fri, 23 Jun 2023 22:27:06 GMT</pubDate>
<description>&lt;p&gt;成为 &lt;code&gt;Geek&lt;/code&gt; 众多步的其中一步,捣鼓 &lt;code&gt;GPG&lt;/code&gt; (&lt;/p&gt;</description>
<content:encoded><![CDATA[<p>成为 <code>Geek</code> 众多步的其中一步,捣鼓 <code>GPG</code> (</p><span id="more"></span><p>密码学让人掉头发,但也很重要,因为它是「普通人」们在赛博空间的基石。任何对「赛博自由」有兴趣的人都应该看过 <code>GPG</code> 之类的文章或书籍吧,相关的加密工具套件让蚂蚁也有了战胜大象的可能,所以 <code>Geek</code> 们乐于折腾这相关方面的东西也不足为奇了。</p><h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>话要从哪里说起呢?思来想去发现没什么想说的,毕竟对 <code>GPG</code> 感兴趣的前置条件是对 「赛博自由」感兴趣,而「赛博自由」也是一个很难说清的东西,就像空气一样。空气当然是很重要的东西,但是去卖力「推销」空气只会让人兴趣乏乏。</p><p>所以我就单纯列列最影响我对「赛博自由」这一观点的来源了:</p><p><a href="https://zh.wikipedia.org/wiki/%E7%BD%91%E7%BB%9C%E7%8B%AC%E7%AB%8B%E5%AE%A3%E8%A8%80">网络独立宣言 - 维基百科</a></p><p>《永久记录》 - 爱德华·斯诺登</p><p><a href="https://www.gnu.org/philosophy/free-sw.zh-cn.html">什么是自由软件? - GNU</a></p><p>零零年左右的那些对互联网有着美好畅想的书籍 - 不管地摊书还是教材</p><h2 id="公钥私钥"><a href="#公钥私钥" class="headerlink" title="公钥私钥"></a>公钥私钥</h2><p><code>GPG</code> 是一个加密套件,覆盖了多种加密算法和类型,但是大家一般折腾的都是「非对称加密」的公钥私钥,简单来说公钥相当于一个带锁箱子,私钥相当于对应锁的钥匙。</p><p>大家都会把公钥发布出来,然后需要进行加密沟通时就用公钥进行加密(相当于将信件转入箱子并锁上),这样只有持有私钥(相当于对应锁的钥匙)的人才能知道内容。</p><p>如果想来点小小的数学风暴可以看:</p><p><a href="https://www.bilibili.com/video/BV1Ts411H7u9/">银行密码系统安全吗质数素数到底有啥用李永乐老师11分钟讲RSA加密算法2018最新</a></p><h2 id="最小系统"><a href="#最小系统" class="headerlink" title="最小系统"></a>最小系统</h2><p> <code>GPG</code> 作为密码学软件让人摸不着头脑,一大堆的相关流程让人生怵,不过从繁杂的电路中拆出一个「最小系统」还是可以的,最后系统没冒烟能用下去就没关系了……大概。</p><p><code>GPG</code> 在一众 <code>Linux</code> 发行版中应该是预装的,所以调出个终端直接用就是了,总体来说使用 <code>gpg --full-gen-key</code> 命令就能生成一个了:</p><ul><li><p>输入 <code>gpg --full-generate-key</code> 开始生成密钥。</p></li><li><p>密钥类型可以选择默认选项: 1 RSA and RSA.</p></li><li><p>密钥长度可以使用 <code>4096</code> 来得到强壮的密钥。</p></li><li><p>选择失效日期,建议 <code>2y</code> (两年)。</p></li></ul><p>按照提示继续设置个人信息,注意名称和邮件在公钥里是公开可见的,所以最好不要填入真名或是公开使用的邮箱。然后就输入一个密码,这个密码会在进行私钥操作的时候需要用到,所以尽量设计得复杂一点同时能记下来(写下来或是放到密码管理器里)。</p><p>生成完以后可以使用 <code>gpg --list-keys [生成密钥时填的邮箱地址]</code> 来列出具体的信息(也可使用 <code>-k</code> 来简写 <code>--list-keys</code> 选项):</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_"># </span><span class="language-bash">例如</span> </span><br><span class="line">gpg --list-keys test@outlook.com</span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">可能输出以下结果</span></span><br><span class="line">sec rsa3072 2023-01-01 [SC]</span><br><span class="line"> XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX</span><br><span class="line">uid [ultimate] test &lt;test@test.com&gt;</span><br><span class="line">ssb rsa3072 2023-1-01 [E]</span><br><span class="line">ssb rsa3072 2023-1-01 [S]</span><br></pre></td></tr></table></figure><p>其中 <code>XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX</code> 的 40 位字符对应的是 <code>finperprint</code> (密钥指纹),在认证其它人的公钥时会用到。</p><h2 id="发布公钥"><a href="#发布公钥" class="headerlink" title="发布公钥"></a>发布公钥</h2><p>接下来就是将公钥发布出去了,具体来说用:</p><p><code>gpg --export --armor [密钥指纹] &gt; pub_key.gpg</code> </p><p>就能将公钥导出为文件,其中 <code>--armor</code> 选项是导出为人类可读形式,可用可不用。</p><p>得到这个公钥之后就是将它发布出去,例如将文件发在网盘上分享;或是将其内容发在共享文档上(需要使用 <code>--armor</code> 选项);或是发布在博客上。</p><p>或是使用 <code>gpg --send-key [密钥指纹]</code> 命令将其发在公共 <code>keyserver</code> 上,但是默认使用的公共 <code>keyserver</code> 没有可删除性,就是说无法撤销,所以要保证生成公钥时没填入敏感信息。</p><h3 id="WKD"><a href="#WKD" class="headerlink" title="WKD"></a>WKD</h3><p>当然也有一种方式是通过 <code>WKD (Web Key Directory)</code> 方式公布自己的公钥,<code>WKD</code> 的思想很简单,就是将邮件地址的哈希串放到规范的指定位置,在使用支持 <code>WKD</code> 的客户端时就会默认从对应的地址导入公钥 <code>GunPG 2.1.23</code> 版后默认从 <code>WKD</code> 地址导入)例如 <code>aheinecke@intevation.de</code> 的邮箱地址就对应 <code>https://intevation.de/.well-known/openPGPkey/hu/g8td9rsyatrazsoiho37j9n3g5ypp34h</code> 。</p><p>要获取 <code>WKD</code> 哈希可以使用 <code>gpg -k --with-wkd-hash [生成密钥时填的邮箱地址]</code> 命令:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">pub rsa3072 2023-01-01 [SC]</span><br><span class="line"> XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX</span><br><span class="line">uid [ultimate] test &lt;test@test.com&gt;</span><br><span class="line"> ****************@test.com</span><br><span class="line">ssb rsa3072 2023-1-01 [E]</span><br><span class="line">ssb rsa3072 2023-1-01 [S]</span><br><span class="line"></span><br></pre></td></tr></table></figure><p>其中 <code>****************</code> 那串字符串对应的就是 <code>WKD </code> 哈希。</p><p>之后可以使用 <code>gpg --export [生成密钥时填的邮箱地址] &gt; [WKD 哈希]</code> 导出为文件,然后放到对应的服务器上,如果使用 <code>Nginx</code> 可以在邮箱对应的域名(如 <code>aheinecke@intevation.de</code> 对应 <code>intevation.de</code> 域名)配置文件下这样写:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">location /.well-known/openpgpkey/hu &#123;</span><br><span class="line"> add_header Access-Control-Allow-Origin *;</span><br><span class="line"> alias /var/www/html/.well-known/openpgpkey/hu; #对应的具体路径</span><br><span class="line">&#125; </span><br><span class="line">location /.well-known/openpgpkey/policy &#123; # 可能一些旧版实现会用到这个路径</span><br><span class="line"> add_header Access-Control-Allow-Origin *;</span><br><span class="line"> alias /var/www/html/.well-known/openpgpkey/hu; #对应的具体路径</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure><p>之后可以在其它账户或设备上使用 <code>gpg --locate-key [生成密钥时填的邮箱地址]</code> 来测试能否导入公钥(需 <code>GunPG 2.1.23</code> 及以后版本)。</p><h2 id="验证公钥"><a href="#验证公钥" class="headerlink" title="验证公钥"></a>验证公钥</h2><p>非对称加密的一个致命处就是如何保证收到的公钥真的是所发布的人呢?所以需要进行确认,最理想的做法是将公钥拷到移动设备上然后肉身跟需要交流的人碰面然后互换公钥。当然赛博空间上很难做到这一点,所以需要设立多个源进行交叉验证,例如在网盘分享公钥出来然后在博客上公布出密钥指纹;将公钥通过邮件发送然后通过电话方式通知密钥指纹等,这样才能防止可能潜在的欺骗行为。</p><p>比如我通过 <code>WKD</code> 方式发布了公钥,那么我要在博客的相关页面公布出指纹来方便他人确认。</p><h2 id="以及……"><a href="#以及……" class="headerlink" title="以及……"></a>以及……</h2><p>选用一个支持这些操作的客户端,比如 <code>Thunderbird</code> 进行加解密操作并不算太复杂,可参见自由软件基金会写的指南:</p><p><a href="https://emailselfdefense.fsf.org/zh-hans/">电子邮件加密指南 - FSF</a></p><p>当然 <code>GPG</code> 还有其它的用法比如签名或是文件加解密等,或是硬件设备之类的,但是这些就太掉入「兔子洞」了。</p><p>同时 <code>GPG</code> 作为一个加密中的 「瑞士军刀」为了广泛用途也带来了很多其它问题,所以其实更适合作为一个「兜底方案」。平常应该使用专门针对使用场景的设计方案例如文件加密使用 <a href="https://github.com/FiloSottile/age">Age</a> ,聊天使用 <a href="https://matrix.org/">Matrix</a> 等。</p><h2 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h2><ul><li><a href="https://ulyc.github.io/2021/01/13/2021%E5%B9%B4-%E7%94%A8%E6%9B%B4%E7%8E%B0%E4%BB%A3%E7%9A%84%E6%96%B9%E6%B3%95%E4%BD%BF%E7%94%A8PGP-%E4%B8%8A/">2021年用更现代的方法使用PGP- Ulyc</a></li><li><a href="https://idawnlight.com/2022/gpg-key-rotation-notes/">GPG 密钥轮换小记 - <a href="https://idawnlight.com/">余光的部落格</a></a></li><li><a href="https://wiki.gnupg.org/WKD">Web Key Directory (WKD) &#x2F; Web Key Service (WKS) what is the difference? - gunpgp wiki</a></li><li><a href="https://www.uriports.com/blog/setting-up-openpgp-web-key-directory/">Setting up OpenPGP Web Key Directory (WKD) - uriports</a></li><li><a href="https://www.ruanyifeng.com/blog/2013/07/gpg.html">GPG入门教程 - 阮一峰的网络日志</a></li></ul>]]></content:encoded>
<category domain="https://blog.southfox.me/categories/%E6%8A%80%E6%9C%AF/">技术</category>
<category domain="https://blog.southfox.me/tags/GPG/">GPG</category>
<category domain="https://blog.southfox.me/tags/%E8%87%AA%E6%89%98%E7%AE%A1/">自托管</category>
<comments>https://blog.southfox.me/2023/06/GPG%20%E6%B5%85%E5%B0%9D%E8%BE%84%E6%AD%A2/#disqus_thread</comments>
</item>
<item>
<title>使用 Mastodon 作为博客的评论系统</title>
<link>https://blog.southfox.me/2023/06/%E4%BD%BF%E7%94%A8%20Mastodon%20%E4%BD%9C%E4%B8%BA%E5%8D%9A%E5%AE%A2%E7%9A%84%E8%AF%84%E8%AE%BA%E7%B3%BB%E7%BB%9F/</link>
<guid>https://blog.southfox.me/2023/06/%E4%BD%BF%E7%94%A8%20Mastodon%20%E4%BD%9C%E4%B8%BA%E5%8D%9A%E5%AE%A2%E7%9A%84%E8%AF%84%E8%AE%BA%E7%B3%BB%E7%BB%9F/</guid>
<pubDate>Fri, 16 Jun 2023 11:20:30 GMT</pubDate>
<description>&lt;p&gt;又在博客的评论系统上左右摇摆了,就算没有人来评论。&lt;/p&gt;</description>
<content:encoded><![CDATA[<p>又在博客的评论系统上左右摇摆了,就算没有人来评论。</p><span id="more"></span><p>之前写过一篇<a href="https://blog.southfox.me/2022/01/%E4%B8%BA%E5%8D%9A%E5%AE%A2%E6%94%AF%E6%8C%81%E8%AF%84%E8%AE%BA%E7%B3%BB%E7%BB%9F/">使用 Giscus 作为博客评论系统</a>的文章,一年下来的使用体验感受良好,只需要经过一点点配置就能为博客嵌入一个支持 <code>Markdown</code> 支持、代码高亮、表情回应、邮件通知、数据背靠 <code>GitHub</code>的评论系统,性价比十分之高。但代价也是背靠 <code>GitHub</code> 作为一个大商业公司「发病」是一个不断扔骰子的过程随着时间流逝扔出个「大发病」的概率将会趋近于必然。可能是什么「大会员」或是「API 收大费」。为了避免最坏情况发生所以有必要准备一些备选方案。</p><p>比如 <a href="https://cusdis.com/">Cusdis</a> 是我之前尝试过一阵的评论系统方案,虽然各方面都比较优秀,但是它上面的一些小小「毛刺」最终让我放弃继续使用(主要是一些样式问题),更大的原因也是我开始觉得为了一年不到十多条的评论是否有必要开一个数据库+评论系统。</p><p>所以最后是打算复用一些已经建立的应用作为博客的评论系统,例如 <a href="https://cactus.chat/">cactus</a> 评论系统就可以使用 <code>Matrix</code> 聊天协议作为博客的评论系统。不过我觉得着有点「重」了,而且 <code>Matrix</code> 主流实现 <code>Synapse</code> 对于房间、媒体管理这些支持并不算太好,要是被恶意刷请求之后很难清理干净。</p><p>所以最后将目光放向了 <code>Mastodon</code> ,现在谷歌上搜索 <code>mastodon blog comment</code> 就能搜索出很多方案本次我也是参touqiefenghe了其中两篇的解决方案</p><p><a href="https://blog.thms.uk/2023/02/mastodon-comments">Adding comments to your blog, powered by mastodon</a></p><p><a href="https://danielpecos.com/2022/12/25/mastodon-as-comment-system-for-your-static-blog/">Mastodon as comment system for your static blog </a></p><p>主要思想就是利用 <code>Mastodon</code> 的帖子 <code>API</code> 获取一条博文下的所有回复,然后处理后插入的指定位置,并不是太复杂。</p><h2 id="实现"><a href="#实现" class="headerlink" title="实现"></a>实现</h2><p>作为一个备选方案我并没有删掉之前基于 <code>Giscus</code> 的评论方案,现在是处于共存状态。要启用基于 <code>Mastodon</code> 的方案就在文章的元数据中指定 <code>fedi_url</code> 这个变量:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">&lt;% if (item.no_comment)&#123; %&gt;</span><br><span class="line"> &lt;!-- no comment --&gt;</span><br><span class="line">&lt;% &#125; else &#123; %&gt;</span><br><span class="line"> &lt;% if (item.fedi_url)&#123; %&gt;</span><br><span class="line"> &lt;div id=&quot;comments&quot;&gt;</span><br><span class="line"> &lt;p id=&quot;mastodon-comments-list&quot;&gt;&lt;/p&gt;</span><br><span class="line"> &lt;script src=&quot;&lt;%- url_for(&#x27;./js/fedicomment.js&#x27;) %&gt;&quot; post-url=&quot;&lt;%- item.fedi_url %&gt;&quot;&gt; async&lt;/script&gt;</span><br><span class="line"> &lt;/div&gt;</span><br><span class="line"> &lt;noscript&gt;Enable JavaScript to view the comments.&lt;/a&gt;&lt;/noscript&gt;</span><br><span class="line"> &lt;% &#125; else &#123; %&gt;</span><br><span class="line"> &lt;script src=&quot;https://giscus.app/client.js&quot;</span><br><span class="line">data-*=&quot;……&quot;</span><br><span class="line"> async&gt;</span><br><span class="line"> &lt;/script&gt;</span><br><span class="line"> &lt;% &#125; %&gt;</span><br><span class="line">&lt;% &#125; %&gt;</span><br></pre></td></tr></table></figure><p>然后引入 <code>fedicomment.js</code> 这个文件,不直接通过模板直接写入主要还是因为自己自找没趣设置了 <code>CSP</code> 禁止 <code>inline javascript</code> 。</p> <figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&lt;script src=&quot;&lt;%- url_for(&#x27;./js/fedicomment.js&#x27;) %&gt;&quot; post-url=&quot;&lt;%- item.fedi_url %&gt;&quot;&gt; async&lt;/script&gt;</span><br></pre></td></tr></table></figure><p>这一段指定了 <code>post-url</code> 这个属性,作为一个变量传入脚本文件里,参见:<a href="https://stackoverflow.com/questions/14904378/get-data-attribute-of-script-tag">Get data attribute of script tag?</a></p><p>之后在脚本文件里将作为全局变量调用:</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> post_url = <span class="variable language_">document</span>.<span class="property">currentScript</span>.<span class="title function_">getAttribute</span>(<span class="string">&quot;post-url&quot;</span>);</span><br></pre></td></tr></table></figure><p>实际的脚本文件课参见 <code>GitHub</code> 上: <a href="https://github.com/SouthFox-D/SouthFox-D.github.io/blob/hexo/themes/freemind/source/js/fedicomment.js">fedicomment.js</a> (毕竟要是直接复制过来也太凑字数了),不过实际也是整合了前面提到的两篇参考文章。</p><h2 id="缺点"><a href="#缺点" class="headerlink" title="缺点"></a>缺点</h2><p><strong>麻烦:</strong>使用这套方案的最大特点就是要多一步操作,因为 <code>Mastodon</code> 的帖子 <code>id</code> 是根据时间戳生成的,不能提前知晓。所以得在 Mastodon 发好文然后获取帖子链接才能插入到博文这里。或许通过配置自动构建的形式使用帐号的 <code>token</code> 预先发好帖然后自动插回文件再提交是种解决办法,但是肯定少不了折腾。而且虽说是在博客上的评论系统但是不能在博客上直接评论。</p><p><strong>管理:</strong>如果不是身为站点管理员的话,那么将无法管理帖文下恶意评论,只能在站点层面的封禁才能移除评论。而且即使身为管理,想要删除单条帖文还得先进行「检举」操作标记这条帖文,然后在管理后台才能删除单条帖文的操作。</p><p><strong>限制:</strong>如果站点开启了「安全模式」的话,那么将无法直接调用帖文的 <code>API</code> ,这样自然谈不上在博客中显示评论了。</p><h3 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h3><p>总体来说,对于想复用服务的人或是联邦爱好者来说可以一试,不过其实相比 <code>Mastodon</code> ,直接在博客上用 <code>Serveless</code> 函数平台服务兼容 <code>ActivityPub</code> 协议似乎是个更好的选择?不过这就相当于从依赖 <code>GitHub</code> 改为依赖其它平台了……</p>]]></content:encoded>
<category domain="https://blog.southfox.me/categories/%E6%8A%80%E6%9C%AF/">技术</category>
<category domain="https://blog.southfox.me/tags/%E6%8A%80%E6%9C%AF/">技术</category>
<category domain="https://blog.southfox.me/tags/Mastodon/">Mastodon</category>
<category domain="https://blog.southfox.me/tags/%E8%81%94%E9%82%A6%E5%AE%87%E5%AE%99/">联邦宇宙</category>
<comments>https://blog.southfox.me/2023/06/%E4%BD%BF%E7%94%A8%20Mastodon%20%E4%BD%9C%E4%B8%BA%E5%8D%9A%E5%AE%A2%E7%9A%84%E8%AF%84%E8%AE%BA%E7%B3%BB%E7%BB%9F/#disqus_thread</comments>
</item>
<item>
<title>2022年终总结</title>
<link>https://blog.southfox.me/2023/02/2022%E5%B9%B4%E7%BB%88%E6%80%BB%E7%BB%93/</link>
<guid>https://blog.southfox.me/2023/02/2022%E5%B9%B4%E7%BB%88%E6%80%BB%E7%BB%93/</guid>
<pubDate>Thu, 02 Feb 2023 02:22:57 GMT</pubDate>
<description>&lt;p&gt;都二月份了!&lt;/p&gt;</description>
<content:encoded><![CDATA[<p>都二月份了!</p><span id="more"></span><p>今年的年终总结来得晚是因为去年末今年初得病外加农历新年无所事事浑浑噩噩打游戏,不过《开拓者:正义之怒》还是挺好玩的,一种单人跑团代餐。</p><h2 id="自托管"><a href="#自托管" class="headerlink" title="自托管"></a>自托管</h2><h3 id="回流"><a href="#回流" class="headerlink" title="回流"></a>回流</h3><p><code>2022</code> 年想必我的关键词是 <code>自托管</code> 一词了,一些常用的服务自己搭起来,在上面也费了很多功夫(不过也有很多功夫也是处于一种折腾了最后没怎么用的状态)。虽然前几年自己也在上面折腾过一些东西,不过这次面向到整个互联网感觉还是很不一样的,让我体会到了零几年的教科书绘声绘色介绍互联网的感觉,整个人类的宝库……和远在天涯海角的人……联系……</p><p>小时候被妈妈带着的时候,通过企业很早就接触到了互联网,第一个打开的网站好像是什么小游戏网站吧,太小了!甚至连当初的情绪都不记得了,新奇?幸福?还是对滑鼠的小球更感兴趣?然后也因为实在没办法去照料,小学一年级就开始全宿制。这个年纪根本就没有全宿制的安排,都是宿管阿姨在照料。不过我似乎也挺乐在其中,可能我就是那样一种自己能陪自己玩的人吧。</p><p>就在这时侯除了玩沙坑也就只能读读书了,或许是这时的书深深影响了我吧,书中对互联网的畅想搭配上蜻蜓点水般的体验,造就了我对于互联网不切实际的幻想。可惜现在互联网成为了大家眼中时好时坏的工具,像是在一望无际的荒原中行走。</p><p>没想到二十年后早期互联网的感觉又冒出来了,也许就互联网也像时尚界一样,二十年来一次回流吧。</p><h3 id="若水"><a href="#若水" class="headerlink" title="若水"></a>若水</h3><p>自托管的好处就是数据在自己手中了,当然实际情况还是要打个问号,甚至惊叹号的。因为自托管面临的问题实在太多了,其中一个方面只要碰上一次「大失败」就要黯灭。但是谁叫这种自在感就是令人舒畅呢?在避无可避的「大失败」来临前再作弄一阵子吧。</p><h2 id="Emacs"><a href="#Emacs" class="headerlink" title="Emacs"></a>Emacs</h2><p>当然还有一件事就是找到了一个能折腾好久的「玩具」,<code>Emacs</code>。对此也没有什么好说的,因为这一年的博客百分之八十都在谈它。当然很多时候是假喜欢,很多东西都没有深入了解过,但没关系,它就在那里,直到我再也忍受不了它的毛病为止,我应该还能在摆弄上几年吧。</p><h2 id="面纱"><a href="#面纱" class="headerlink" title="面纱"></a>面纱</h2><p>严格来讲,去年定下的目标和展望都没有实现多少,关爱身体啦、认清「现实」啦、磨炼技术啦等等,不过其实回头来看,盯着石像上的面纱,还是舞动了几分的。世界依然朦胧,但我已在月色下盯着湖面发呆,即使挨不到清晨的到来,此刻还算不赖。但是随着世界终于回归正轨,今年还是要稍微「正常」一下,至少为一个目标所努力。</p><p>2022 年,对我来说是失去的一年,就像「失去的十年」一样(气候变化上的说法),大家在扯皮中丧失希望,嘟囔着十年什么事都没干成,世界末日已经来临。但回过头来看世界并没有被毁灭,在一地鸡毛里,一些希望正在发展。</p><p>没有毁灭,但是问题依然存在,但随着绝望的潮水退去,踩在「正常」的大地上……或许回想起几年后的场景,没来头闲逛时发现当时的痕迹我一拍脑门想到,「啊,当时的水位~竟然有这么高吗?」</p>]]></content:encoded>
<category domain="https://blog.southfox.me/categories/%E9%9A%8F%E7%AC%94/">随笔</category>
<category domain="https://blog.southfox.me/tags/%E9%9A%8F%E7%AC%94/">随笔</category>
<category domain="https://blog.southfox.me/tags/%E5%B9%B4%E7%BB%88%E6%80%BB%E7%BB%93/">年终总结</category>
<comments>https://blog.southfox.me/2023/02/2022%E5%B9%B4%E7%BB%88%E6%80%BB%E7%BB%93/#disqus_thread</comments>
</item>
<item>
<title>Emacs 使用再记3</title>
<link>https://blog.southfox.me/2023/01/Emacs-%E4%BD%BF%E7%94%A8%E5%86%8D%E8%AE%B0%EF%BC%883%EF%BC%89/</link>
<guid>https://blog.southfox.me/2023/01/Emacs-%E4%BD%BF%E7%94%A8%E5%86%8D%E8%AE%B0%EF%BC%883%EF%BC%89/</guid>
<pubDate>Sun, 15 Jan 2023 15:22:05 GMT</pubDate>
<description>&lt;p&gt;两种喜欢的事遇到一起,多是一件美事啊。&lt;/p&gt;</description>
<content:encoded><![CDATA[<p>两种喜欢的事遇到一起,多是一件美事啊。</p><span id="more"></span><p>折腾 <code>Emacs</code> 最重要就是开心,而能开心的事莫过于想实现的功能已经提前有人去实现了,这时候只要愉快导包就好了。</p><h2 id="Mastodon"><a href="#Mastodon" class="headerlink" title="Mastodon"></a>Mastodon</h2><p><a href="https://codeberg.org/martianh/mastodon.el">Mastodon.el</a> 是一个 <code>Emacs</code> 平台的 <code>Mastodon</code> 客户端,为什么啥事都要用 <code>Emacs</code> 来实现呢?因为只要将文字送入 <code>Emacs</code> 解析,那么就能够和其它包进行联动,这可是很诱人的事啊。</p><h3 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h3><p><code>Mastodon.el</code> 也已经上传到了 <code>MELPA</code> 上面,可以直接进行安装。使用时只要指定实例地址和用户名:</p><figure class="highlight lisp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">(<span class="name">setq</span> mastodon-instance-url <span class="string">&quot;https://social.instance.org&quot;</span></span><br><span class="line"> mastodon-active-user <span class="string">&quot;example_user&quot;</span>)</span><br></pre></td></tr></table></figure><p>然后直接 <code>M-x mastodon</code> 运行指令,然后就会往剪贴板复制一串授权地址,粘贴到登陆的了实例浏览器进行打开,获取授权码再复制回 <code>Emacs</code> 就能完全授权了。</p><h3 id="使用"><a href="#使用" class="headerlink" title="使用"></a>使用</h3><p>当然如果是使用 <code>Doom emacs</code> 配置集的话,自带的 <code>vim</code> 按键绑定会覆盖掉 <code>mastodon.el</code> 的自带按键设定,所以还是得自己设置一下。</p><figure class="highlight lisp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br></pre></td><td class="code"><pre><span class="line">(<span class="name">map!</span> <span class="symbol">:leader</span></span><br><span class="line"> <span class="symbol">:prefix</span> (<span class="string">&quot;o&quot;</span>)</span><br><span class="line"> <span class="symbol">:desc</span> <span class="string">&quot;Mastodon&quot;</span> <span class="string">&quot;M&quot;</span> #&#x27;mastodon)</span><br><span class="line"></span><br><span class="line">(<span class="name">map!</span> <span class="symbol">:after</span> mastodon</span><br><span class="line"> <span class="symbol">:map</span> mastodon-mode-map</span><br><span class="line"> <span class="symbol">:n</span> <span class="string">&quot;[ [&quot;</span> #&#x27;mastodon-tl--goto-prev-toot</span><br><span class="line"> <span class="symbol">:n</span> <span class="string">&quot;] ]&quot;</span> #&#x27;mastodon-tl--goto-next-toot</span><br><span class="line"> <span class="symbol">:n</span> <span class="string">&quot;g k&quot;</span> #&#x27;mastodon-tl--previous-tab-item</span><br><span class="line"> <span class="symbol">:n</span> <span class="string">&quot;g j&quot;</span> #&#x27;mastodon-tl--next-tab-item</span><br><span class="line"></span><br><span class="line"> <span class="symbol">:n</span> <span class="string">&quot;q&quot;</span> #&#x27;kill-current-buffer</span><br><span class="line"> <span class="symbol">:n</span> <span class="string">&quot;Q&quot;</span> #&#x27;kill-buffer-and-window</span><br><span class="line"></span><br><span class="line"> <span class="comment">;;; timelines</span></span><br><span class="line"> <span class="symbol">:n</span> <span class="string">&quot;#&quot;</span> #&#x27;mastodon-tl--get-tag-timeline</span><br><span class="line"> <span class="symbol">:n</span> <span class="string">&quot;A&quot;</span> #&#x27;mastodon-profile--get-toot-author</span><br><span class="line"> <span class="symbol">:n</span> <span class="string">&quot;F&quot;</span> #&#x27;mastodon-tl--get-federated-timeline</span><br><span class="line"> <span class="symbol">:n</span> <span class="string">&quot;H&quot;</span> #&#x27;mastodon-tl--get-home-timeline</span><br><span class="line"> <span class="symbol">:n</span> <span class="string">&quot;L&quot;</span> #&#x27;mastodon-tl--get-local-timeline</span><br><span class="line"> <span class="symbol">:n</span> <span class="string">&quot;N&quot;</span> #&#x27;mastodon-notifications-get</span><br><span class="line"> <span class="symbol">:n</span> <span class="string">&quot;O&quot;</span> #&#x27;mastodon-profile--my-profile</span><br><span class="line"> <span class="symbol">:n</span> <span class="string">&quot;P&quot;</span> #&#x27;mastodon-profile--show-user</span><br><span class="line"> <span class="symbol">:n</span> <span class="string">&quot;T&quot;</span> #&#x27;mastodon-tl--thread</span><br><span class="line"></span><br><span class="line"> <span class="comment">;;; toot actions</span></span><br><span class="line"> <span class="symbol">:n</span> <span class="string">&quot;K&quot;</span> #&#x27;mastodon-toot--bookmark-toot-toggle</span><br><span class="line"> <span class="symbol">:n</span> <span class="string">&quot;R&quot;</span> #&#x27;mastodon-toot--toggle-boost</span><br><span class="line"> <span class="symbol">:n</span> <span class="string">&quot;c&quot;</span> #&#x27;mastodon-tl--toggle-spoiler-text-in-toot</span><br><span class="line"> <span class="symbol">:n</span> <span class="string">&quot;C&quot;</span> #&#x27;mastodon-toot--copy-toot-url</span><br><span class="line"> <span class="symbol">:n</span> <span class="string">&quot;o&quot;</span> #&#x27;mastodon-url-lookup</span><br><span class="line"> <span class="symbol">:n</span> <span class="string">&quot;d&quot;</span> #&#x27;mastodon-toot--delete-toot</span><br><span class="line"> <span class="symbol">:n</span> <span class="string">&quot;D&quot;</span> #&#x27;mastodon-toot--delete-draft-toot</span><br><span class="line"> <span class="symbol">:n</span> <span class="string">&quot;f&quot;</span> #&#x27;mastodon-toot--toggle-favourite</span><br><span class="line"> <span class="symbol">:n</span> <span class="string">&quot;r&quot;</span> #&#x27;mastodon-toot--reply</span><br><span class="line"> <span class="symbol">:n</span> <span class="string">&quot;u&quot;</span> #&#x27;mastodon-tl--update</span><br><span class="line"> <span class="symbol">:n</span> <span class="string">&quot;v&quot;</span> #&#x27;mastodon-tl--poll-vote</span><br><span class="line"></span><br><span class="line"> <span class="comment">;;; toot!</span></span><br><span class="line"> <span class="symbol">:n</span> <span class="string">&quot;t&quot;</span> #&#x27;mastodon-toot</span><br><span class="line"></span><br><span class="line"> <span class="comment">;;; mastodon additions</span></span><br><span class="line"> <span class="symbol">:n</span> <span class="string">&quot;S&quot;</span> #&#x27;mastodon-search--search-query</span><br><span class="line"> <span class="symbol">:n</span> <span class="string">&quot;V F&quot;</span> #&#x27;mastodon-profile--view-favourites</span><br><span class="line"> <span class="symbol">:n</span> <span class="string">&quot;V B&quot;</span> #&#x27;mastodon-profile--view-bookmarks</span><br><span class="line"> <span class="symbol">:n</span> <span class="string">&quot;V L&quot;</span> #&#x27;mastodon-tl--view-list-timeline</span><br><span class="line"> )</span><br></pre></td></tr></table></figure><p>第一处就是使用 <code>SPC o M</code> 来打开 <code>mastodon.el</code> 这个包,实现快速摸鱼,第二处设置则是照虎画猫其他人的<a href="https://github.com/coutego/evil-collection/blob/master/modes/mastodon/evil-collection-mastodon.el">配置</a>来实现的,虽然没看文档(坏习惯),但是猜测 <code>:map mastodon-mode-map</code> 是选择指定那个模式下的按键配置,<code>:n</code> 是覆盖 <code>vim</code> 那个模式下的按键绑定,<code>n</code> 应该是普通模式。</p><p>按键绑定改来改去,要在不影响原本的 <code>hjkl</code> 和 <code>wby</code> 常用指令还要做到方便(自己)记忆还是有点难的,毕竟能兼容了原本按键绑定进行复制粘贴起也比较好操作。</p><p>总体来看还是倾向于一个补充,毕竟 <code>Emacs</code> 网络相关的操作确实不太行,跟 <code>Web</code> 端确实是不能比的,但是能够快速摸鱼外加和其它包联携的潜力(比如打开收藏夹进行进行分析;直接拷贝嘟文内容送入待办等),还要啥自行车呢。</p><h2 id="Matrix"><a href="#Matrix" class="headerlink" title="Matrix"></a>Matrix</h2><p>接下来就是聊天了,其实作为和 <code>Emacs</code> 同一个时代的产品,<code>IRC</code> 自然是支持众多的,不过我已经选择另一款聊天协议了 <a href="https://matrix.org/">Matrix</a> 。</p><h3 id="安装-1"><a href="#安装-1" class="headerlink" title="安装"></a>安装</h3><p>虽然也有一些包支持但是现在还在积极开发的也就 <a href="https://github.com/alphapapa/ement.el">ement.el</a> 其作者 <code>alphapapa</code> 也是有名的 <code>Emacs</code> 使用者了,写了很多流行的包。</p><p><code>ement.el</code> 现在也是上传到了 <code>GNU ELPA</code> 可以直接进行安装,但是实现起来那叫一个坑多啊,虽然大部分都是自己的问题。</p><p>安装后首先要登陆,但发现一直登陆不上去,之后排查是自己的 <a href="https://matrix-org.github.io/synapse/latest/delegate.html#well-known-delegation">Delegation</a> 功能没有加上 <code>https://</code> 例如 <code>return 200 &#39;&#123;&quot;m.homeserver&quot;: &#123;&quot;base_url&quot;: &quot;synapse.matrix.org&quot;&#125;&#125;&#39;; </code> ,应该是 <code>return 200 &#39;&#123;&quot;m.homeserver&quot;: &#123;&quot;base_url&quot;: &quot;https://synapse.matrix.org&quot;&#125;&#125;&#39;;</code> 。</p><p>没有做到这一点导致 <code>ement.el</code> 发起的链接不成功,虽然很想指责一下是包的健壮性不足但姑且还是把责任揽到自己身上吧……</p><p>登陆之后发现解密不了加密消息,看说明才发现是 <code>ement.el</code> 不原生支持加密功能,想想也对,想支持得用 <code>ELisp</code> 去造轮子太麻烦了(当然我觉得主要原因是作者对于用 <code>Matrix</code> 发送加密消息没什么兴趣)。</p><h3 id="配置"><a href="#配置" class="headerlink" title="配置"></a>配置</h3><p>不过还有曲线救国方案就是用 <a href="https://github.com/matrix-org/pantalaimon">pantalaimon</a> ,一个代理程序,可以将加密消息解密提供给其它不支持加密的客户端使用。</p><p>安装上可以直接用 <code>pip</code> 进行安装 <code>pip install pantalaimon</code> 之后得编辑 <code>~/.config/pantalaimon/pantalaimon.conf</code> 下的配置文件指定实例地址和相关配置。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">[配置名称,随便填]</span><br><span class="line">Homeserver = https://实例地址</span><br><span class="line">ListenAddress = localhost</span><br><span class="line">ListenPort = 8009</span><br><span class="line">VerifySessions = False</span><br><span class="line">UseKeyring = False</span><br><span class="line">IgnoreVerification = True</span><br></pre></td></tr></table></figure><p>注意如果启用了 <a href="https://matrix-org.github.io/synapse/latest/delegate.html#well-known-delegation">Delegation</a> 功能的话实例地址得填真正使用的服务地址。后面三行是不断试错加进去的,因为这个程序真的是缺文档,所以也不清楚对实际运行有没有影响。</p><p>之后再启动程序 <code>pantalaimon --log-level debug</code> ,但是现在还没有真正运行,首先在 <code>Emacs</code> 里进行登陆并且指定使用的地址:</p><p>按下 <code>M-S </code> 运行指定本地反代的地址的指令:</p><figure class="highlight lisp"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">(<span class="name">ement-connect</span> <span class="symbol">:uri-prefix</span> <span class="string">&quot;http://localhost:8009&quot;</span>)</span><br></pre></td></tr></table></figure><p>然后输入帐号密码进行登陆,看日志应该能发现有所输出,等待到数据同步后 <code>Emacs</code> 显示了房间列表后。切换到另一个已经登陆的客户端上应该能发现两个设备进行登陆,一个叫 <code>pantalaimon</code> 另一个是随机字符串是 <code>ement.el</code> 使用的。两个都显示未支持加密功能。这时先用 <code>Emacs</code> 进入一个开启加密的房间然后用 <code>ement-room-send-message</code> 指令发送一条消息,理所当然的不会成功,因为 <code>pantalaimon</code> 还没通过验证,但现在应该会显示 <code>pantalaimon</code> 设备变成支持加密的未知设备了。</p><p>这时在开启一个终端输入 <code>panctl</code> 指令进入控制,参考<a href="https://www.cogitri.dev/posts/10-pantalaimon-setup/">这篇文章</a>进行验证操作 ,具体来说就是用指令 <code>start-verification @自己帐号:自己实例 @自己帐号:自己实例 已经登陆的设备的设备号</code> 发起验证,然后用那一个已经登陆的设备确实验证请求开启交叉验证……其中可能会卡住或许要多发起几次。</p><p>确实 <code>emoji</code> 匹配后就使用 <code>confirm-verification @自己帐号:自己实例 @自己帐号:自己实例 已经登陆的设备的设备号</code> 指令验证 <code>pantalaimon</code> 设备。转过头去 <code>Emacs</code> 里再尝试发起加密房间的消息查看是否成功。</p><h3 id="再配置"><a href="#再配置" class="headerlink" title="再配置"></a>再配置</h3><p>之后如果希望将 <code>pantalaimon</code> 作为系统服务开机自启的话就发现不行,会遇到相关总线问题,因为其中一些 <code>pyDbus</code> 什么的调用导致无法挂在后台吧。</p><p>权宜之计是按照这个<a href="https://github.com/matrix-org/pantalaimon/issues/144#issuecomment-1345473181">说法</a>手动编辑 <code>pantalaimon</code> 包下的 <code>ui.py</code> 文件关闭 <code>UI</code> 功能:</p><figure class="highlight py"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">UI_ENABLED = <span class="literal">False</span></span><br></pre></td></tr></table></figure><p>然后就能当作 <code>service</code> 进行管理理,代价就是无法使用 <code>panctl</code> 命令,不过只要没有再配置的需求还是能接受的,或是从一开始就使用 <code>Docker</code> 然后按照这<a href="https://github.com/matrix-org/pantalaimon/issues/144#issuecomment-1376163550">说法</a>进行配置。</p><h3 id="再再配置"><a href="#再再配置" class="headerlink" title="再再配置"></a>再再配置</h3><p>然后记得配置</p><figure class="highlight lisp"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">(<span class="name">setq</span> ement-save-sessions <span class="literal">t</span>)</span><br></pre></td></tr></table></figure><p>将会话数据保留下来,要不然每次登陆都会新申请一个设备,每开一次 <code>Emacs</code> 来这样一次那很快就要达到上百个设备了。</p><p>配置此选项后关闭 <code>Emacs</code> 应该能注意到关闭 <code>Emacs</code> 会将会话数据写入,没有的话还得重启 <code>Emacs</code> 使用<code>(ement-connect :uri-prefix &quot;http://localhost:8009&quot;)</code> 指令再登陆几次。检查 <code>ement-sessions-file</code> 变量是否有被设置,默认是 <code>&quot;~/.cache/ement.el&quot;</code> ,到该路径检查,有没有设置反代地址和保存了相关 <code>token</code> ,有的话就万事大吉了,之后也可以直接用 <code>ement-connect</code> 直接登陆,因为反代地址已经保存了所以也不用再去特意指定。</p><h3 id="再再再配置"><a href="#再再再配置" class="headerlink" title="再再再配置"></a>再再再配置</h3><p>跟 <code>mastodon.el</code> 问题一样,<code>Doom emacs</code> 的按键绑定会覆盖掉相关绑定,不过我想将上面让人头大的解决掉按键绑定就不是什么难题了。</p><h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p>两款常用服务配置下来那就挺让人舒适的了,快速刷轴摸鱼,聊天也可以在 <code>Emacs</code> 实现,主要优点是不走 <code>Web</code> 端的话,资源是比较省的,不用再加载几兆几十兆的脚本外加浏览器吃掉的内存了,两种喜欢的事加起来,多是一件美事啊。</p>]]></content:encoded>
<category domain="https://blog.southfox.me/categories/%E6%8A%80%E6%9C%AF/">技术</category>
<category domain="https://blog.southfox.me/tags/%E6%8A%80%E6%9C%AF/">技术</category>
<category domain="https://blog.southfox.me/tags/Matrix/">Matrix</category>
<category domain="https://blog.southfox.me/tags/Mastodon/">Mastodon</category>
<comments>https://blog.southfox.me/2023/01/Emacs-%E4%BD%BF%E7%94%A8%E5%86%8D%E8%AE%B0%EF%BC%883%EF%BC%89/#disqus_thread</comments>
</item>
<item>
<title>Arch 系统随便用暨 Emacs 使用再记2</title>
<link>https://blog.southfox.me/2022/12/Arch%E7%B3%BB%E7%BB%9F%E9%9A%8F%E4%BE%BF%E7%94%A8%E6%9A%A8Emacs%E4%BD%BF%E7%94%A8%E5%86%8D%E8%AE%B0%EF%BC%882%EF%BC%89/</link>
<guid>https://blog.southfox.me/2022/12/Arch%E7%B3%BB%E7%BB%9F%E9%9A%8F%E4%BE%BF%E7%94%A8%E6%9A%A8Emacs%E4%BD%BF%E7%94%A8%E5%86%8D%E8%AE%B0%EF%BC%882%EF%BC%89/</guid>
<pubDate>Sat, 03 Dec 2022 20:00:00 GMT</pubDate>
<description>&lt;p&gt;我还挺喜欢用 &lt;code&gt;Manjaro&lt;/code&gt; 的,就喜欢这种低人一等的感觉。&lt;/p&gt;</description>
<content:encoded><![CDATA[<p>我还挺喜欢用 <code>Manjaro</code> 的,就喜欢这种低人一等的感觉。</p><span id="more"></span><p>反正系统相关的我也不懂啦,用着玩的,不想对这些 <code>Linux</code> 发行版使用什么个排序算法争出个最优。用 <code>Manjaro</code> 单纯就是安装方便同时教程好找点……不过最近(二十天前),当我更新包时突然开始报错「<code>libssl3.0</code> 未找到。」去网上搜发现五六天前 <code>Manjaro</code> 论坛就有此问题,但也只是捕风捉影并没有实际解决方案。</p><p>之后电脑新开一些应用已经打不开了,在终端里也只会一直显示库错误,估计系统已经成为一个僵尸了,一旦重新启动估计就会立马爆炸吧(重新启动果然如此,连终端环境都进不了)。</p><p>没办法,重装吧!对于这种问题向来我都是重装解决一切问题的,心想这次还是不要用 <code>KDE</code> 了,试试其它桌面环境吧,结果没想到 <code>Manjaro</code> 系统安装程序会卡在最后一步安装系统引导上(现在想来应该是智熄操作没有选到 <code>UEFI</code> 选项导致的)。</p><h2 id="Arch-随便用"><a href="#Arch-随便用" class="headerlink" title="Arch 随便用"></a>Arch 随便用</h2><h3 id="懒不动"><a href="#懒不动" class="headerlink" title="懒不动"></a>懒不动</h3><p>那么既然已经装不下了那就换个口味吧,换成更上游的 <code>Arch</code> 。之前一直没用 <code>Arch</code> 的原因就是系统安装没有提供一个图形化界面,就觉得很麻烦,不过查 <code>wiki</code> 时发现现在会附带一个 <code>archinstall</code> 程序辅助安装,那么就尝试用用看吧,能这么惬意决定重装也是因为大部分数据都是放在另一快数据盘上,是和系统盘分开的。</p><p>第一时间就发现的是 <code>Arch</code> 的镜像挺小的1G 还不到,但之后就发现为什么是这样了。因为只包括了基本的组件,要成为一个能用系统的东西还得从网上下,在运行 <code>archinstall</code> 还要需求联网还卡住了几分钟的我才顿悟到……</p><p>不过说是辅助安装但也只是一个选项菜单而已,方便选择磁盘之类的,不过总比没有好吧,选好系统环境、额外包、挂载目录进行安装……最后报错识别不了另一个盘的某个分区,又不是在安装的盘上为什么还要去管其它盘上的事啊,重试了几次后依然卡在这里,没办法,想懒懒不动了,只好自己手动装了。</p><h3 id="随便装"><a href="#随便装" class="headerlink" title="随便装"></a>随便装</h3><p>手动装就一步一步自己慢慢盯着了,看着 <code>wiki</code> 再顺便开几个教程帖,之后慢慢对着下来,无非就是选择分区然后挂载点之类的(我这种大懒狐一个 <code>/</code> 就够了),然后选择速度快的镜像站把基础系统组件还有网络管理包之类的装上去就完事了。</p><p>之后 <code>unmount</code>,重启,噔噔噔……新系统就来了,不过没有选择桌面环境所以显示的还是挺「刻板印象里的黑客风」黑黢黢命令窗口。桌面环境想了想还是选择 <code>GNOME</code> 吧,没错,我就喜欢卡又多 <code>BUG</code> 低人几等的感觉,只能说习惯的力量还是惊人的,本来其实还想体验 <code>i3</code> 环境来着但是到现在一次都没打开过(</p><p>安装重新登陆后,一个毛坯房 <code>GNOME</code> 环境就出来了,看看系统占用,发现真的挺轻量的,内存占用在 1.5G 左右,只有 <code>Manjaro</code> 一半左右。感想就是 <code>Minecraft</code> 热门整合包和自己配整合包吧,现在自用的这款系统还是有点缺东少西,比如最重要的代理和 <code>Emacs</code> 了。</p><h3 id="随便折腾"><a href="#随便折腾" class="headerlink" title="随便折腾"></a>随便折腾</h3><p>代理的事因为相关软件挂在 <code>yay</code> 上,但是安装 <code>yay</code> 要自己构建下一大堆 <code>GO</code> 相关东西而又需要代理环境,经典先有鸡还是先有蛋了属于是,不过好在可以用其它设备开放的代理环境救救急,这时候才发现 <code>Manjaro</code> 默认把 <code>yay</code> 集成到了自己的源中是有理由的……</p><p>安装 <code>yay</code> 后就能愉快的继续偷 <code>Arch</code> 的……嘶,我现在就是 <code>Arch</code> 系统了,所以是光明正大来用!</p><h4 id="编辑器"><a href="#编辑器" class="headerlink" title="编辑器"></a>编辑器</h4><p>首先是使用 <code>neovim</code> <code>Emacs</code> 这位大爷还是等所有东西都搞定了在把祂请过来吧。</p><h4 id="字体"><a href="#字体" class="headerlink" title="字体"></a>字体</h4><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo pacman -S noto-fonts-cjk</span><br></pre></td></tr></table></figure><p>庞大的汉字在计算机世界还是要折腾一番的,不下中文字体开个浏览器就全是口口口的豆腐框了,所以要 <code>noto(fu)</code> 字体来拯救一下。</p><h4 id="输入法"><a href="#输入法" class="headerlink" title="输入法"></a>输入法</h4><p>好在在之前系统自爆前把 <code>Rime</code> 的配置文件抢救了下来,所以直接使用相应包:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo pacman -S fcitx5-im fcitx5-rime</span><br></pre></td></tr></table></figure><p>然后编辑 <code>/etc/environment</code> 文件,添加以下几行</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">GTK_IM_MODULE=fcitx</span><br><span class="line">QT_IM_MODULE=fcitx</span><br><span class="line">XMODIFIERS=@im=fcitx</span><br><span class="line">SDL_IM_MODULE=fcitx</span><br><span class="line">GLFW_IM_MODULE=ibus</span><br></pre></td></tr></table></figure><p>然后重新登录就好了,反正 <a href="https://wiki.archlinuxcn.org/wiki/Fcitx5">ArchWiki</a> 是这么说的,之后把之前备份的 <code>Rime</code> 配置覆盖回 <code>~/.local/share/fcitx5/rime</code> 里就好了,使用的方案是 <a href="https://github.com/mutoe/rime">双拼自然码方案</a>和 <a href="https://github.com/Bambooin/rimerc">rimerc</a> ,毕竟没有网络词和大公司的算法加持,想要加快输入速度只能从自己的手法上入手了。</p><h4 id="按键绑定"><a href="#按键绑定" class="headerlink" title="按键绑定"></a>按键绑定</h4><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo pacman -S gnome-tweak-tool</span><br></pre></td></tr></table></figure><p>突然发现 <code>Gnome tweak</code> 里面的 <code>Keyboard &amp; Mouse</code> 里有一个 <code>Emacs Input</code> 选项,打开它后就能在操作系统里实现 <code>Emacs Keybinding</code> 了,就 <code>C-a</code> 将光标移动到行首这种的,真实 <code>Emacs EveryWhere</code> 了。然后 <code>/usr/share/themes/Emacs/gtk-2.0-key/gtkrc</code> 文件是具体的配置,可以让猫猫来看具体定义了哪些按键(我是指,<code>cat</code> 命令……)</p><h4 id="窗口切换"><a href="#窗口切换" class="headerlink" title="窗口切换"></a>窗口切换</h4><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo pacman -S gnome-shell-extensions</span><br></pre></td></tr></table></figure><p>然后在 <code>gnome-extensions</code> 开启 <code>Window List</code> 选项,这样就能像 <code>Win</code> 系统一样显示一个任务栏在窗口底部,如果这不是默认启用的我真想不到平常使用 <code>GNOME</code> 是怎么切换窗口的?难道这是 <code>Win</code> 系统带来的我永远摆脱不了的烙印?</p><h4 id="钥匙环儿"><a href="#钥匙环儿" class="headerlink" title="钥匙环儿"></a>钥匙环儿</h4><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo pacman -S gnome-keyring</span><br></pre></td></tr></table></figure><p>我一般使用 <code>Nextcloud</code> 的桌面客户端来同步数据的,如果缺少这个就会无限首次重新需求登录,似乎 <code>Minecraft</code> 启动器也会有这个问题,所以还是得装的。</p><h4 id="其它"><a href="#其它" class="headerlink" title="其它"></a>其它</h4><p>其它的有了 <code>yay</code> 也挺容易装了比如 <code>oh-my-zsh</code> 之类的,看情况调个顺眼的用用,</p><p>其中 <code>keyd</code> 这个应用可以改键,把 <code>Esc</code> 和 <code>Caps</code> 调换之类的,虽然 <code>GNOME</code> 里有什么组件能改不过我也是路径依懒惯了……</p><h2 id="Emacs"><a href="#Emacs" class="headerlink" title="Emacs"></a>Emacs</h2><p>终于最后就是把这位神请回来了,</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo pacman -S emacs-nativecomp ripgrep</span><br></pre></td></tr></table></figure><p>虽然完全搞不懂但是听说加了 <code>nativecomp</code> 会让运行速度有改善的样子,之后克隆下来 <code>doomemacs</code> 的配置仓库,将之前的备份过的配置文件放入 <code>~/.doom</code> 里,然后开始安装,之后就只能等了,几百个包安装编译啥的估计要登上十多分钟。</p><h3 id="邮件"><a href="#邮件" class="headerlink" title="邮件"></a>邮件</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">yay -S mu isync</span><br></pre></td></tr></table></figure><p>参照<a href="https://blog.lazkani.io/posts/email-setup-with-isync-notmuch-afew-msmtp-and-emacs/">这篇文章</a>完成 <code>mbsync(isync)</code> 设定,然后 <code>mbsync -a</code> 拉取邮件,然后参照<a href="https://liujiacai.net/blog/2021/03/05/emacs-love-mail-feed/">这篇文章</a>完成 <code>mu4e</code> 配置(<code>mu4e</code> 在 <code>doomemacs</code> 也有相应配置可启用),然后:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">export XAPIAN_CJK_NGRAM=true</span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">只需要执行一次 init可以指定多个邮件地址</span></span><br><span class="line">mu init --my-address your-mail@qq.com --my-address your-mail@gmail.com -m ~/.mail</span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">index 在每次收取邮件后都需要执行mu4e 可以配置自动执行</span></span><br><span class="line">mu index</span><br></pre></td></tr></table></figure><p>就能为邮件建立索引,之后在 <code>Emacs</code> 里使用 <code>Spc o m </code> 即可打开 <code>mu4e</code> 界面进行使用了。</p><h3 id="Latex"><a href="#Latex" class="headerlink" title="Latex"></a>Latex</h3><p><code>Emacs</code> 里预览公式需要 <code>latex</code>,使用</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo pacman -S texlive-langextra</span><br></pre></td></tr></table></figure><p>安装 <code>texlive</code> 发行版同时还要指定是 <code>extra</code> 包才能应付公式预览。</p><h3 id="Emacs-everywhere"><a href="#Emacs-everywhere" class="headerlink" title="Emacs everywhere"></a>Emacs everywhere</h3><p>类似于空间文里的随身空间,直接在任意能输入文字的地方启动一个 <code>Emacs</code> 编辑器,这样就不用离开自己的安乐窝了。</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo pacman -S xclip xdotool xorg-xprop xorg-xwininfo</span><br></pre></td></tr></table></figure><p>然后在 <code>gnome</code> 里指定一个快捷键绑定上 <code>emacsclient --eval &quot;(emacs-everywhere)&quot;</code> 就能想用就用 <code> Emacs</code> 这个随身编辑器了。</p>]]></content:encoded>
<category domain="https://blog.southfox.me/categories/%E6%8A%80%E6%9C%AF/">技术</category>
<category domain="https://blog.southfox.me/tags/%E6%8A%80%E6%9C%AF/">技术</category>
<category domain="https://blog.southfox.me/tags/%E7%B3%BB%E7%BB%9F/">系统</category>
<category domain="https://blog.southfox.me/tags/Arch/">Arch</category>
<comments>https://blog.southfox.me/2022/12/Arch%E7%B3%BB%E7%BB%9F%E9%9A%8F%E4%BE%BF%E7%94%A8%E6%9A%A8Emacs%E4%BD%BF%E7%94%A8%E5%86%8D%E8%AE%B0%EF%BC%882%EF%BC%89/#disqus_thread</comments>
</item>
<item>
<title>Emacs再记1传教二度</title>
<link>https://blog.southfox.me/2022/08/Emacs%E5%86%8D%E8%AE%B0%EF%BC%881%EF%BC%89%EF%BC%9A%E4%BC%A0%E6%95%99%E4%BA%8C%E5%BA%A6/</link>
<guid>https://blog.southfox.me/2022/08/Emacs%E5%86%8D%E8%AE%B0%EF%BC%881%EF%BC%89%EF%BC%9A%E4%BC%A0%E6%95%99%E4%BA%8C%E5%BA%A6/</guid>
<pubDate>Tue, 16 Aug 2022 14:17:20 GMT</pubDate>
<description>&lt;p&gt;论都 2022 年了为什么要用 Emacs 。&lt;/p&gt;</description>
<content:encoded><![CDATA[<p>论都 2022 年了为什么要用 Emacs 。</p><span id="more"></span><p><code>Emacs</code> 最早可以追溯到 <code>1975</code>年,经过多年发展诞生了许多分支,不过现在都是特指 <code>GNU Emacs</code>,时间没有葬送这款软件,直至现在也有不少人在使用它。</p><h2 id="Emacs-之世界观"><a href="#Emacs-之世界观" class="headerlink" title="Emacs 之世界观"></a>Emacs 之世界观</h2><p>经过将近一年的使用,我对于 <code>Emacs</code> 也有了更多的了解索性再写一遍第1篇吧。</p><p><code>Emacs</code> ,其<a href="https://www.gnu.org/software/emacs/">官网</a>对它的描述是一个可拓展的、客制化的自由免费文本编辑器—and more。当然这么多天用下来我发现其实 <code>Emacs</code> 本质并不是一个文本编辑器,因为它有一片自己的世界……</p><p>举个不恰当的例子来说,其它文本编辑器里编辑文本像是挥舞武器,安装一个插件并运用其功能像是吟唱一个魔法,其底层实现方式大家都一样,之间的区别不是很大。</p><p>而 <code>Emacs</code>,表面看是挥舞武器,但实际是因为心中有战斗的决心所以才能具现一把专属武器并战斗,表面上看是吟唱魔法,但实际上是因为其所在世界是一个失落的高科技世界,吟唱魔法其实是在和空中散落的纳米单元进行沟通然后由单元实现具体效果……虽然最后 <code>Emacs</code> 和其他文本编辑器实现了同样效果,但是它们的「世界观」是有根本不同的。</p><h2 id="自由"><a href="#自由" class="headerlink" title="自由"></a>自由</h2><p>查看 <code>Emacs</code> 代码仓库就能发现,其构成代码有近六成是由一个叫作 <code>Emacs Lisp</code> 的语言构成的,<code>Emacs</code> 以其说是一款文本编辑器倒不如说是作为 <code>Emacs Lisp</code> 的运行环境,打开软件那出现的窗口和菜单,是 <code>Emacs</code> 自己不断修改自己的体现。</p><p>这样的实现方式,更是让 <code>Emacs</code> 对于用户的态度和其他编辑器有很大不同,再举个不恰当的例子来说:</p><p>其它文本编辑器就像一个人类:</p><ul><li><p>想要其它功能的话请指定,比如沟通语言从英语切换成汉语……什么?想要克林贡语,不好意思,没有,请自行查询插件商店吧。</p></li><li><p>商店里没有?请自己参照接口标准自行实现一个吧?什么,你还想要修改大脑的核心功能?不可能!太危险了!</p></li><li><p>真想要修改大脑核心功能的话,请自行修改「源代码」去。</p></li></ul><p><code>Emacs</code></p><ul><li>犹如一个不定形的阿米巴变形虫,时刻不停在蠕动、变形……</li><li>想要切换到特定功能?好啊好啊,请自行在「配置文件」里指定吧……</li><li>没有想要的功能?那请自行在「配置文件」里实现具体功能吧……等我重载之后就能看到新功能了……</li><li>想干预一个核心功能?随便……</li></ul><p>所以对于 <code>Emacs</code> 来说,它不像其他软件的 <code>.ini</code> <code> .env</code> 一样,只能附加几个参数或者在 <code>A</code> 和 <code>B</code> 已有的功能切换,在 <code> Emacs</code> 里,没有 <code>C</code> 功能,你可以自行在「配置文件」里实现,因为「配置文件」即是「源代码」,因为 <code>Emacs</code> 是在那旧时代下诞生的软件,它完全信任用户。</p><h2 id="混乱"><a href="#混乱" class="headerlink" title="混乱"></a>混乱</h2><p>当然自由的代价就是导致了其黑魔法满天飞,大魔法师用着呼风唤雨,而学徒却看着一大堆选择摸不着头脑。</p><p>不过随着社区的聚集,现在也出现了 <a href="https://www.spacemacs.org/">Spacemacs</a> 和 <a href="https://github.com/doomemacs/doomemacs">Doom emacs</a> 这样的整合网上优秀第三方包和配置的配置集,新手直接使用的话可以在一开始时就能体验到 <code>Emacs</code> 生态里的大部分优秀功能。</p><h2 id="低效"><a href="#低效" class="headerlink" title="低效"></a>低效</h2><p>建立在 <code>Emacs Lisp</code> 上的 <code>Emacs</code> 其一大特征就是……慢……当然大多数场景不会感受到,但是出现了这个情况就真的有点锻炼耐心了。而且 <code>Emacs</code> 说好听点是历史悠久,难听点就是历史包袱过重了,一些上古代码散落在各处,非常高效地拖慢了 <code>Emacs</code> 在一些场景的性能让其低效(感谢 <code>Emacs</code> 让我在 2022 年体会到了多图杀猫的效果)。</p><h2 id="甜美错觉"><a href="#甜美错觉" class="headerlink" title="甜美错觉"></a>甜美错觉</h2><p>如果在多了解一点的话,可能就会发现很多人都在吐槽 <code>Emacs</code> 用着像是一款操作系统一样,收发电子邮件、记录笔记、安排待办、写代码、甚至进行聊天。因为 <code>Emacs</code> 其「万物皆文本」的哲学,代码是文本,笔记和待办也是,甚至文件列表或是菜单栏也是(文本定义九宫格.jpg也借助于 <code>Emacs Lisp</code> 的灵活性,只要你能想到有关于文字的编辑功能,你就能够去实现。</p><p>而且这些功能都做为一个包被 <code>Emacs</code> 载入,所以这些功能还能进行联动,比如将待办里的任务作为电子邮件发送,将文件夹内的全文搜索结果裁剪为笔记,在笔记中嵌入可以执行的代码……因为这就是 <code>Emacs</code> ,虽然实现的过程中可能像是在布满乐高的地板上赤脚行走,让人痛苦不堪感到沮丧,或许在 <code>Emacs</code> 里实现还不如直接用专用软件效果来得好,但是 <code>Emacs</code> 它就是让人产生了这样的错觉:</p><blockquote><p>我们必须实现,我们必将实现。</p></blockquote><h2 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h2><p><a href="https://nyk.ma/posts/emacs-intro/">Emacs 自力求生指南 ── 前言</a></p><p><a href="https://github.com/redguardtoo/mastering-emacs-in-one-year-guide/blob/master/guide-zh.org">一年成为Emacs高手 (像神一样使用编辑器)</a></p><p><a href="https://manateelazycat.github.io/emacs/2018/12/11/study-emacs.html">怎么学习 Emacs ? 达到真正融汇贯通的境界? </a></p>]]></content:encoded>
<category domain="https://blog.southfox.me/categories/%E6%8A%80%E6%9C%AF/">技术</category>
<category domain="https://blog.southfox.me/tags/%E6%8A%80%E6%9C%AF/">技术</category>
<category domain="https://blog.southfox.me/tags/Emacs/">Emacs</category>
<comments>https://blog.southfox.me/2022/08/Emacs%E5%86%8D%E8%AE%B0%EF%BC%881%EF%BC%89%EF%BC%9A%E4%BC%A0%E6%95%99%E4%BA%8C%E5%BA%A6/#disqus_thread</comments>
</item>
<item>
<title>如何改变自己</title>
<link>https://blog.southfox.me/2022/08/%E5%A6%82%E4%BD%95%E6%94%B9%E5%8F%98%E8%87%AA%E5%B7%B1/</link>
<guid>https://blog.southfox.me/2022/08/%E5%A6%82%E4%BD%95%E6%94%B9%E5%8F%98%E8%87%AA%E5%B7%B1/</guid>
<pubDate>Mon, 01 Aug 2022 22:25:48 GMT</pubDate>
<description>&lt;p&gt;基本就是 Kurz 的视频的梳理:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.bilibili.com/video/BV1334y1j7DD&quot;&gt;【Kurz】如何改变自己的人生@青知字幕组-哔哩哔哩&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=75d_29QWELk&quot;&gt;Change Your Life One Tiny Step at a Time - Youtube&lt;/a&gt;&lt;/p&gt;</description>
<content:encoded><![CDATA[<p>基本就是 Kurz 的视频的梳理:</p><p><a href="https://www.bilibili.com/video/BV1334y1j7DD">【Kurz】如何改变自己的人生@青知字幕组-哔哩哔哩</a></p><p><a href="https://www.youtube.com/watch?v=75d_29QWELk">Change Your Life One Tiny Step at a Time - Youtube</a></p><span id="more"></span><p><img src="https://media.southfox.me/ipfs/bafkreigayiupw7d5gg5pterrb3o6j4p23lyzqdn63ud3fs5ggj3tujuiya?filename=image.png" alt="img"></p><p>当今互联网充斥着各种成功学金句、传说和鸡汤,要是你没做成什么事,那么一切都是你的错!</p><p>但事实是做出改变就是一件艰难的事。</p><h1 id="丛林比喻"><a href="#丛林比喻" class="headerlink" title="丛林比喻"></a>丛林比喻</h1><p><img src="https://media.southfox.me/ipfs/bafkreid4btr3e35nhnzkmvwn7g3dwqjozr3qgxi4iyxrhiucuefm4uv5oa?filename=image.png" alt="img"></p><p>外部环境就像是一片错综复杂犹如迷宫般的雨林,在里面生活可是件很累的事,还需耗费大量的精力。所以经过千万年的进化,人类的大脑开始学会走捷径。</p><p><img src="https://media.southfox.me/ipfs/bafkreidth26bi54ritzgzi3srdszk73jmr66b4dqd3dg3sciqhtsgtsfli?filename=image.png" alt="img"></p><p>所做出的每一次相同的决定,就像是在雨林中的一个位置上走了一遍,当走的次数多了,大脑就开始重视起这条路径。这条路径就开始变成了一条舒适又高效的道路了,走起这条路来那真是不带任何犹豫的……</p><p>如果自己想要做的事仍是一片丛林,那么有什么事已经成为高速路了呢?</p><ul><li>看到手机就开始下意识的解锁</li><li>躺床上看手机看到深夜哪怕在后半夜叹道自己今天依旧在浪费时间</li><li>每次到吃饭的地方总会选择同一家餐馆然后点同样的菜</li></ul><p>随着年龄的增长,所建造的高速路也不断增多,所以说年纪越大越不容易改变,因为又有谁能富有强大的拓荒精神抛下高效且安全的高速路,去面对未知且危险的丛林呢?</p><h1 id="例行和习惯"><a href="#例行和习惯" class="headerlink" title="例行和习惯"></a>例行和习惯</h1><p><img src="https://media.southfox.me/ipfs/bafkreicp5345w6vp443dm7lwzx6su7swv5llcnzhtbqit6mujqzgjtquqi?filename=image.png" alt="img"></p><p>例行(惯例)是指按照一定步骤去做的事物,例如按照菜谱煮菜、初学开车等,当为一件例行投入大量时间和精力重复多次后,那么……</p><p><img src="https://media.southfox.me/ipfs/bafkreicqlnedjdzsqlthhitfrnzidshbit4jvf2qpodn2zkkpgj2tscwo4?filename=image.png" alt="img"></p><p>这件例行就会成为一个习惯,习惯是自然发生的,做一件习惯的事不用说服自己,因为……它就是习惯。例如上十年经验的开车、解锁手机并打开某一个社交 APP 等。</p><h2 id="幼儿和导师"><a href="#幼儿和导师" class="headerlink" title="幼儿和导师"></a>幼儿和导师</h2><p><img src="https://media.southfox.me/ipfs/bafkreido3ak6xul5duhfc2nbo3pkwxpk2g4sod7fpe7a2rsqxz4qjtffii?filename=image.png" alt="img"></p><p>人们总会沉溺在自己的坏习惯中无法自拔,事后又后悔不已,那是因为习惯的背后是由一个「幼儿」所掌握,眼里只有现在马上就能得到的满足。</p><p>而很不幸现代社会能马上产生满足事物太多了,袋装薯片、榜上有名的 APP 。沉溺其中也不是件丢人的事,因为它们背后可是站着无数聪明才智之人,重要的是认识到通过自己的意志力战胜这些人是一件困难的事,要思考如何规避避免硬碰硬(例如寻找是否有其它可替代客户端,能否关闭推荐功能或是私人推送功能)。</p><p><img src="https://media.southfox.me/ipfs/bafkreiaq253nj6nbgf6mlwdcrv2qp3oswgit62qhljxvpbd7itzrphlffa?filename=image.png" alt="img"></p><p>而惯例既是由一个「导师」所掌握的,需要消耗珍贵的意志力去计划并执行,意志力通常在一天内都是宝贵的不可再生资源且通常都不能提升上限(尤其对于有 ADHD 特质的人来说)。</p><h2 id="我们联合!"><a href="#我们联合!" class="headerlink" title="我们联合!"></a>我们联合!</h2><p><img src="https://media.southfox.me/ipfs/bafkreia4eg5li2opfoaacxkvi3c6yu3hxuuvbcx23e46lpomnph5nux5gq?filename=image.png" alt="img"></p><p>「幼儿」是亿万年生物进化路上一直伴随着我们的模块,它对于生物的生存至关重要。「导师」是人类千万年来为了适应社会活动进化出来的模块,它很高效且精妙,但也像游戏中的某些武器一样,开不了几下火就会过热。<br>如果需要改变自己,让「幼儿」和「导师」一起为你工作,那么「导师」该如何规划道路的路线,让「幼儿」如何能最小抵抗得为道路完成做努力……</p><h3 id="专注于小目标"><a href="#专注于小目标" class="headerlink" title="专注于小目标"></a>专注于小目标</h3><p><img src="https://media.southfox.me/ipfs/bafkreigz6njoj6ikeeulg63bidoty3fn4t6b4vbycjnhd3fonkmkcecroa?filename=image.png" alt="img"></p><p>不要让躺在待办里的事物是一件吓人的目标,应该是一件每天结束时都能感到有所进展的小目标。让「导师」制定的目标也能像「幼儿」所执行的习惯那样能感到满足感和低抵抗感。</p><p>比如「每天写下五张卡片笔记」或是「每天早上十个深蹲」等。</p><h3 id="易于触发"><a href="#易于触发" class="headerlink" title="易于触发"></a>易于触发</h3><p><img src="https://media.southfox.me/ipfs/bafkreibrke4la2t5qj7lzq6h4jk625zqnn2zzdhjwl4hze5mrngtyai34m?filename=image.png" alt="img"></p><p>这通常来说也是最核心的一步了,如何找到一个触发?习惯的执行需要一个触发,比如看到手机、走到一家餐馆等,而自我决定的触发通常是以闹钟为多数。</p><p>而对于有 ADHD 特质的人来说,能否准确地实施呢?克服 ADHD 特质最需要一个强有力的外在结构也是如此……</p><p>营造一个专用的环境和空间大概有助于此,比如划分出一个专门做这件事的空间,并好好整理一下周围的杂物(杂乱的事物将导致分心的几率大大增加),划分出专门娱乐和学习专用空间(即使缺乏空间也可以在虚拟意义上实现,比如安装两个浏览器,并尽量让自己在学习时只能用专用浏览器)。</p><h3 id="每天重复"><a href="#每天重复" class="headerlink" title="每天重复"></a>每天重复</h3><p>最难的一步,要让例行转为习惯那需要 15~250 天的时间,很多时候坚持不下来就会让一切照旧……还要加上一些自暴自弃的情绪……</p><h3 id="改进"><a href="#改进" class="headerlink" title="改进"></a>改进</h3><p><img src="https://media.southfox.me/ipfs/bafkreigronwruqfwukkhsimsbnlfw6q2mxbeymrib6bsxilgtqyxst2pue?filename=image.png" alt="img"></p><p>在实行的过程也并不是苦修,得尽量让做事的自己少点抵抗,例如放点喜欢的音乐,在跑步时听自己最喜欢的博客等。</p><h1 id="结语"><a href="#结语" class="headerlink" title="结语"></a>结语</h1><p><img src="https://media.southfox.me/ipfs/bafkreiab7e4ivqewy2kfjvz3kofwh7pf3coax5z27tx6u2xvs7h2wwti4q?filename=image.png" alt="img"></p><p>哪怕只是做出了微小的改变,也是往理想的自己靠近一步,改进没有终点,只有方向。</p>]]></content:encoded>
<category domain="https://blog.southfox.me/categories/%E9%9A%8F%E7%AC%94/">随笔</category>
<category domain="https://blog.southfox.me/tags/%E9%9A%8F%E7%AC%94/">随笔</category>
<comments>https://blog.southfox.me/2022/08/%E5%A6%82%E4%BD%95%E6%94%B9%E5%8F%98%E8%87%AA%E5%B7%B1/#disqus_thread</comments>
</item>
<item>
<title>Gitea:一款自托管的 Git 服务</title>
<link>https://blog.southfox.me/2022/07/Gitea:%E4%B8%80%E6%AC%BE%E8%87%AA%E6%89%98%E7%AE%A1%E7%9A%84-Git-%E6%9C%8D%E5%8A%A1/</link>
<guid>https://blog.southfox.me/2022/07/Gitea:%E4%B8%80%E6%AC%BE%E8%87%AA%E6%89%98%E7%AE%A1%E7%9A%84-Git-%E6%9C%8D%E5%8A%A1/</guid>
<pubDate>Sun, 17 Jul 2022 19:02:07 GMT</pubDate>
<description>&lt;p&gt;别忘了泡上一杯茶!&lt;/p&gt;</description>
<content:encoded><![CDATA[<p>别忘了泡上一杯茶!</p><span id="more"></span><h2 id="绕不开的存在"><a href="#绕不开的存在" class="headerlink" title="绕不开的存在"></a>绕不开的存在</h2><p>当然,谈到 <code>Git</code> 服务时,肯定绕不过 <code>GitHub</code> 。为什么要大费周章自建呢?<code>GitHub</code> 不好吗?</p><p>是很好,但是也没那么好,因为:</p><ul><li><code>GitHub</code> 是一家商业公司,那么首先盈利肯定是首要目的,为了不倒闭,指不准未来哪天就变质了。</li><li>同上,如果还是个自由软件爱好者的话,想必 <code>GitHub</code> 最近一些事件带来的臭味也不必我再提了……</li><li><code>Git</code> 是分布式的,那么选择同样也是……不知道现在还有多少人还傻傻认为 <code>Git</code> 和 <code>GitHub</code> 是一体的呢?</li></ul><p>也可参见 <a href="https://sfconservancy.org/GiveUpGitHub/">GiveUpGitHub</a> 一文章。</p><h2 id="Gitea"><a href="#Gitea" class="headerlink" title="Gitea"></a>Gitea</h2><p><code>Gitea</code> 是一个用 <code>Go</code> 编写、面向自建的、轻量级的 <code>Git</code> 服务。其安装十分便捷,直接下载个可执行文件也可快速搭建起来,当然为了后续跟其它服务联动,还是用 <code>docker-compose</code> 方便点。</p><p>话不多说,新建一个文件夹然后往里建 <code>docker-compose.yml</code> 文件并写入以下配置:</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">version:</span> <span class="string">&quot;3.7&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="attr">services:</span></span><br><span class="line"> <span class="attr">gitea:</span></span><br><span class="line"> <span class="attr">image:</span> <span class="string">gitea/gitea:latest</span></span><br><span class="line"> <span class="attr">container_name:</span> <span class="string">gitea</span></span><br><span class="line"> <span class="attr">restart:</span> <span class="string">unless-stopped</span></span><br><span class="line"> <span class="attr">environment:</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">USER_UID=1000</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">USER_GID=1000</span></span><br><span class="line"> <span class="attr">volumes:</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">./data/gitea:/data</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">/etc/timezone:/etc/timezone:ro</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">/etc/localtime:/etc/localtime:ro</span></span><br><span class="line"> <span class="attr">ports:</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">&quot;127.0.0.1:3000:3000&quot;</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">&quot;2222:22&quot;</span></span><br><span class="line"> <span class="attr">networks:</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">cicd_net</span></span><br><span class="line"></span><br><span class="line"> <span class="attr">drone:</span></span><br><span class="line"> <span class="attr">container_name:</span> <span class="string">drone</span></span><br><span class="line"> <span class="attr">image:</span> <span class="string">drone/drone:latest</span></span><br><span class="line"> <span class="attr">restart:</span> <span class="string">unless-stopped</span></span><br><span class="line"> <span class="attr">depends_on:</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">gitea</span></span><br><span class="line"> <span class="attr">environment:</span></span><br><span class="line"> <span class="comment"># https://docs.drone.io/server/provider/gitea/</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">DRONE_DATABASE_DRIVER=sqlite3</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">DRONE_DATABASE_DATASOURCE=/data/database.sqlite</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">DRONE_GITEA_SERVER=https://my.git.server/</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">DRONE_GIT_ALWAYS_AUTH=false</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">DRONE_RPC_SECRET=changeme...</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">DRONE_SERVER_PROTO=https</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">DRONE_SERVER_HOST=https://cicd.git.server</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">DRONE_GITEA_CLIENT_ID=changeme...</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">DRONE_GITEA_CLIENT_SECRET=changeme...</span></span><br><span class="line"> <span class="attr">ports:</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">&quot;127.0.0.1:3001:80&quot;</span></span><br><span class="line"> <span class="attr">volumes:</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">/var/run/docker.sock:/var/run/docker.sock</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">./data/drone:/data</span></span><br><span class="line"> <span class="attr">networks:</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">cicd_net</span></span><br><span class="line"></span><br><span class="line"> <span class="attr">drone-runner:</span></span><br><span class="line"> <span class="attr">container_name:</span> <span class="string">drone-runner</span></span><br><span class="line"> <span class="attr">image:</span> <span class="string">drone/drone-runner-docker:latest</span></span><br><span class="line"> <span class="attr">restart:</span> <span class="string">unless-stopped</span></span><br><span class="line"> <span class="attr">depends_on:</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">drone</span></span><br><span class="line"> <span class="attr">environment:</span></span><br><span class="line"> <span class="comment"># https://docs.drone.io/runner/docker/installation/linux/</span></span><br><span class="line"> <span class="comment"># https://docs.drone.io/server/metrics/</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">DRONE_RPC_PROTO=http</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">DRONE_RPC_HOST=drone</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">DRONE_RPC_SECRET=changeme...</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">DRONE_RUNNER_NAME=&quot;action-runner&quot;</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">DRONE_RUNNER_CAPACITY=2</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">DRONE_RUNNER_NETWORKS=cicd_net</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">DRONE_DEBUG=false</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">DRONE_TRACE=false</span></span><br><span class="line"> <span class="attr">networks:</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">cicd_net</span></span><br><span class="line"> <span class="attr">volumes:</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">/var/run/docker.sock:/var/run/docker.sock</span></span><br><span class="line"></span><br><span class="line"><span class="attr">networks:</span></span><br><span class="line"> <span class="attr">cicd_net:</span></span><br><span class="line"> <span class="attr">name:</span> <span class="string">cicd_net</span></span><br></pre></td></tr></table></figure><p>因为预想场景是私人自用,所以选择了 <code>SQlite3</code> 数据库,觉得别扭可以自己改掉……</p><p>然后准备两个域名,这里用 <code>my.git.server</code> 域名指定用来运行 <code>Gitea</code> 服务的域名,一个 <code>cicd.git.server</code> 域名用来指定运行后续的自动构建服务的域名(可选)。</p><p>首先为 <code>my.git.server</code> 域名设定<code>DNS</code> 后申请证书,<code>certbot certonly --nginx -d my.git.server</code></p><p>,申请后写入 <code>nginx</code> 配置:</p><figure class="highlight nginx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#不要忘了替换成自己的域名</span></span><br><span class="line"><span class="section">server</span> &#123;</span><br><span class="line"> <span class="attribute">listen</span> <span class="number">80</span>;</span><br><span class="line"> <span class="attribute">listen</span> [::]:<span class="number">80</span>;</span><br><span class="line"> <span class="attribute">server_name</span> my.git.server;</span><br><span class="line"></span><br><span class="line"> <span class="section">location</span> /.well-known/acme-challenge &#123;&#125;</span><br><span class="line"> <span class="section">location</span> / &#123;</span><br><span class="line"> <span class="attribute">return</span> <span class="number">301</span> https://<span class="variable">$host</span><span class="variable">$request_uri</span>;</span><br><span class="line"> &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="section">server</span> &#123;</span><br><span class="line"> <span class="attribute">listen</span> <span class="number">443</span> ssl http2;</span><br><span class="line"> <span class="attribute">listen</span> [::]:<span class="number">443</span> ssl http2;</span><br><span class="line"> <span class="attribute">server_name</span> my.git.server;</span><br><span class="line"></span><br><span class="line"> <span class="attribute">access_log</span> /var/log/nginx/access.log;</span><br><span class="line"> <span class="comment">#root /home/plume/Plume/ ;</span></span><br><span class="line"></span><br><span class="line"> <span class="attribute">ssl_certificate</span> /etc/letsencrypt/live/my.git.server/fullchain.pem;</span><br><span class="line"> <span class="attribute">ssl_certificate_key</span> /etc/letsencrypt/live/my.git.server/privkey.pem;</span><br><span class="line"></span><br><span class="line"> <span class="comment"># for ssl conf: https://cipherli.st/</span></span><br><span class="line"> <span class="attribute">ssl_protocols</span> TLSv1.<span class="number">2</span> TLSv1.<span class="number">3</span>;<span class="comment"># Requires nginx &gt;= 1.13.0 else use TLSv1.2</span></span><br><span class="line"> <span class="attribute">ssl_prefer_server_ciphers</span> <span class="literal">on</span>;</span><br><span class="line"> <span class="attribute">ssl_dhparam</span> /etc/letsencrypt/ssl-dhparams.pem;<span class="comment"># openssl dhparam -out /etc/letsencrypt/ssl-dhparam.pem 4096</span></span><br><span class="line"> <span class="attribute">ssl_ciphers</span> ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384;</span><br><span class="line"> <span class="attribute">ssl_ecdh_curve</span> secp384r1; <span class="comment"># Requires nginx &gt;= 1.1.0</span></span><br><span class="line"> <span class="attribute">ssl_session_timeout</span> <span class="number">10m</span>;</span><br><span class="line"> <span class="attribute">ssl_session_cache</span> shared:SSL:<span class="number">10m</span>;</span><br><span class="line"> <span class="attribute">ssl_session_tickets</span> <span class="literal">off</span>; <span class="comment"># Requires nginx &gt;= 1.5.9</span></span><br><span class="line"> <span class="attribute">ssl_stapling</span> <span class="literal">on</span>; <span class="comment"># Requires nginx &gt;= 1.3.7</span></span><br><span class="line"> <span class="attribute">ssl_stapling_verify</span> <span class="literal">on</span>; <span class="comment"># Requires nginx =&gt; 1.3.7</span></span><br><span class="line"> <span class="attribute">resolver</span> <span class="number">9.9.9.9</span> <span class="number">80.67.169.12</span> valid=<span class="number">300s</span>;</span><br><span class="line"> <span class="attribute">resolver_timeout</span> <span class="number">5s</span>;</span><br><span class="line"> <span class="attribute">add_header</span> Strict-Transport-Security <span class="string">&quot;max-age=63072000; includeSubDomains; preload&quot;</span>;</span><br><span class="line"> <span class="attribute">add_header</span> X-Frame-Options DENY;</span><br><span class="line"> <span class="attribute">add_header</span> X-Content-Type-Options nosniff;</span><br><span class="line"> <span class="attribute">add_header</span> X-XSS-Protection <span class="string">&quot;1; mode=block&quot;</span>;</span><br><span class="line"> <span class="comment">#如果不想显示外链图片可把 img-src 一栏改掉</span></span><br><span class="line"> <span class="attribute">add_header</span> Content-Security-Policy <span class="string">&quot;default-src &#x27;self&#x27;; img-src *; frame-ancestors &#x27;self&#x27;; frame-src https:&quot;</span>;</span><br><span class="line"></span><br><span class="line"> <span class="section">location</span> / &#123;</span><br><span class="line"> <span class="attribute">proxy_pass</span> http://localhost:3000/;</span><br><span class="line"> <span class="attribute">proxy_set_header</span> Host <span class="variable">$http_host</span>;</span><br><span class="line"> <span class="attribute">proxy_set_header</span> X-Real-IP <span class="variable">$remote_addr</span>;</span><br><span class="line"> <span class="attribute">proxy_set_header</span> X-Forwarded-For <span class="variable">$proxy_add_x_forwarded_for</span>;</span><br><span class="line"> <span class="attribute">proxy_set_header</span> X-Forwarded-Proto <span class="variable">$scheme</span>;</span><br><span class="line"> <span class="attribute">client_max_body_size</span> <span class="number">50m</span>;</span><br><span class="line"> &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>之后 <code>nginx -s reload</code> 重载配置,然后 <code>docker-compose up -d gitea</code> 把 <code>Gitea</code> 服务启动,之后前往 <code>my.git.server</code> 地址进行配置并新建一个管理员账户。</p><h3 id="Drone"><a href="#Drone" class="headerlink" title="Drone"></a>Drone</h3><p>到此服务就基本可用了,但是我相信很多人割舍不下 <code>GitHub</code> 的一个原因就是因为它的 <code>Actions</code> 很香。不过可以选择 <code>Drone</code> ,一个同样用 <code>GO</code> 编写的、轻量级的自动构建服务,也可以让体验往 <code>GitHub Actions</code> 靠拢。</p><p>首先为 <code>cicd.git.server</code> 域名申请证书并写入 <code>nginx</code> 配置文件,配置文件可复用上面的,只需要更改相关域名和 <code>nginx</code> 配置文件里的 <code>location /</code> 里的 <code>proxy_pass</code> 端口号就行(本例子是 <code>3001</code>)。</p><p>之后为 <code>Drone</code> 和 <code>Gitea</code> 联动做准备,登陆自己 <code>Gitea</code> 实例的帐号→设置→应用→创建新的 OAuth2 应用程序,应用名称随意填(本例子填 drone重定向 URI 填入 <code>https://cicd.git.server/login</code> (替换成自己的域名)。</p><p>点击创建应用→会生成一个客户端 ID 和一个客户端密钥→替换到上述 <code>docker-compose.yml</code> 里 <code>drone</code> 一栏的 <code>DRONE_GITEA_CLIENT_ID</code> 和 <code>DRONE_GITEA_CLIENT_SECRET</code> 。</p><p>之后再使用 <code>openssl rand -hex 16</code> 命令生成一串随机字符串给 <code>DRONE_RPC_SECRET</code> 使用(有两个地方需要替换)。</p><p>确认无误后使用 <code>docker-compose up -d</code> 启动全部服务,之后前往 <code>https://cicd.git.server</code> 地址查看是否正常运行,是的话点击登陆,看是否能够和 <code>Gitea</code> 进行联动,如果显示错误请检查是否与上述配置一致(例如我之前就遇到了无法验证的错误,排查后发现是某个路径多带了一个 <code>/</code> 导致之后生成的验证路径出错,去掉 <code>/</code> 之后就正常了)。</p><h3 id="仓库操作"><a href="#仓库操作" class="headerlink" title="仓库操作"></a>仓库操作</h3><p>因为宿主机的 <code>22</code> 端口已被占用,所以克隆或者 <code>PUSH</code> 仓库使用的端口应该为 <code>2222</code>,觉得别扭也有其他教程教如何与宿主机共用端口,我就不折腾了(反正 <code>Just work!</code> )。</p><p>还有如果为网站使用了 <code>Cloudflare</code> 之类的 <code>CDN</code> 服务的话,那么 <code>SSH</code> 协议也是不能用的,得用网站域名下的真实 <code>IP</code> 地址克隆或 <code>PUSH</code> 仓库。</p><p>如果像我什么都没改的话,想要克隆仓库就会得到这么一个奇怪的地址:</p><p><code>git clone ssh://git@机子真实IP:2222/用户名/仓库名.git</code></p><p>反正 <code>Just work</code> </p><h3 id="一个案例"><a href="#一个案例" class="headerlink" title="一个案例"></a>一个案例</h3><p>那么接下来就讲讲我用这套服务的案例吧,自动生成文件并推送一个 <code>HUGO</code> 博客。</p><p>首先为仓库根目录写下 <code>.drone.yml</code> 文件:</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">kind:</span> <span class="string">pipeline</span></span><br><span class="line"><span class="attr">name:</span> <span class="string">build</span></span><br><span class="line"></span><br><span class="line"><span class="attr">steps:</span></span><br><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">build</span></span><br><span class="line"> <span class="attr">image:</span> <span class="string">klakegg/hugo:alpine</span></span><br><span class="line"> <span class="attr">commands:</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">hugo</span></span><br><span class="line"></span><br><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">deploy</span></span><br><span class="line"> <span class="attr">image:</span> <span class="string">node</span></span><br><span class="line"> <span class="attr">environment:</span></span><br><span class="line"> <span class="attr">CLOUDFLARE_API_TOKEN:</span></span><br><span class="line"> <span class="attr">from_secret:</span> <span class="string">api_token</span></span><br><span class="line"> <span class="attr">CLOUDFLARE_ACCOUNT_ID:</span></span><br><span class="line"> <span class="attr">from_secret:</span> <span class="string">account_id</span></span><br><span class="line"> <span class="attr">commands:</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">npm</span> <span class="string">install</span> <span class="string">-g</span> <span class="string">wrangler</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">npx</span> <span class="string">wrangler</span> <span class="string">pages</span> <span class="string">publish</span> <span class="string">public</span> <span class="string">--project-name</span> <span class="string">项目名</span> <span class="string">--commit-dirty=true</span></span><br></pre></td></tr></table></figure><p>可以见到和 <code>GitHub Actions</code> 的配置还是挺像的,琢磨琢磨还是挺快上手的。</p><p>其中 <code>steps</code> 指定了所需步骤,<code>image</code> 指定了需要什么样的 <code>docker</code> 镜像,第一栏拉取了 <code>klakegg/hugo</code> 镜像并使用 <code>hugo</code> 命令生成静态文件。</p><p>之后是 <code>deploy</code> 一栏里的 <code>environment</code> ,像 <code>GitHub</code> 一样,密钥相关可以使用 <code>secret</code> 功能导入到环境变量中,可在自己的 <code>cicd.git.server</code> →相关仓库→ <code>Settings</code> → <code>Secrets</code> 里进行导入。</p><p>接下来使用 <code>node</code> 镜像安装了个 <code>wrangler</code> 包,这是 <code>Cloudflare Pages</code> 部署要用的,如果也用 <code>Cloudflare Pages</code> 部署的话可以参考:</p><p><a href="https://developers.cloudflare.com/workers/wrangler/commands/#pages">Wrangler pages commands</a></p><p><a href="https://developers.cloudflare.com/workers/wrangler/ci-cd/">Running Wrangler in CI&#x2F;CD</a></p><p>PS不得不吐槽相关操作首先必须要用 <code>project create</code> 命令里的 <code>--production-branch</code> 显式指定部署分支否则接下来的部署都会被识别为预览而不会真正部署到……被这个坑卡了好一会……</p><p>之后再进行相关操作后应该能看见自己 <code>Gitea</code> 实例也有小绿勾了(小红叉也行,至少证实自动部署服务有在用了)!</p><h3 id="加主题"><a href="#加主题" class="headerlink" title="加主题"></a>加主题</h3><p>默认主题还挺程序员风格的,既然都自建了,肯定要加点主题快乐一下了。</p><p>以<a href="https://codeberg.org/Freeplay/Gitea-Modern/">现代主题</a>为例。</p><p>如果是以上面的配置文件搭建起来的话要在自己文件夹下找到 <code>./data/gitea/gitea</code> 路径,并在里头新建 <code>public/css</code> 下 <code>wget https://codeberg.org/Freeplay/Gitea-Modern/raw/branch/main/Gitea/theme-gitea-modern.css</code> 获取主题文件。</p><p>之后再编辑 <code>./data/gitea/gitea/conf/app.ini</code> 文件,在最后面加上:</p><figure class="highlight ini"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">请自己想象下……</span><br><span class="line">因为现在我服务器炸了……</span><br></pre></td></tr></table></figure><p>之后再用 <code>docker-compose down</code> 和 <code>docker-compose up -d</code> 重启服务。</p><h3 id="安全"><a href="#安全" class="headerlink" title="安全"></a>安全</h3><p>如果没有相关要求,请务必关闭实例的注册功能。</p><p>参见,<a href="https://imlonghao.com/59.html">记一次自建 Gitea + Drone 实例被挖矿的经历</a></p><p>也是修改 <code>./data/gitea/gitea/conf/app.ini</code> 里的:</p><figure class="highlight ini"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">请自己查阅……</span><br><span class="line">因为我现在服务器炸了</span><br></pre></td></tr></table></figure><p>之后再用 <code>docker-compose down</code> 和 <code>docker-compose up -d</code> 重启服务,然后再检查站点是否关闭了注册入口。</p><h3 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h3><p><a href="https://blog.ruanbekker.com/blog/2021/03/09/cicd-with-droneci-and-gitea-using-docker-compose/">CICD With DroneCI and Gitea Using Docker Compose</a></p><p><a href="https://docs.gitea.io/en-us/">Gitea Docs</a></p><p><a href="https://docs.drone.io/">Drone Docs</a></p><p><a href="https://tech.ray247k.com/blog/202106-drone-cicd-3-advanced-cron-job/">透過 Drone 建立自動部署流程,部署排程設定與權限管理 - 薛丁格的工程師</a></p>]]></content:encoded>
<category domain="https://blog.southfox.me/categories/%E6%8A%80%E6%9C%AF/">技术</category>
<category domain="https://blog.southfox.me/tags/%E6%8A%80%E6%9C%AF/">技术</category>
<category domain="https://blog.southfox.me/tags/%E5%BB%BA%E7%AB%99/">建站</category>
<comments>https://blog.southfox.me/2022/07/Gitea:%E4%B8%80%E6%AC%BE%E8%87%AA%E6%89%98%E7%AE%A1%E7%9A%84-Git-%E6%9C%8D%E5%8A%A1/#disqus_thread</comments>
</item>
<item>
<title>二二年六月梦记</title>
<link>https://blog.southfox.me/2022/06/%E4%BA%8C%E4%BA%8C%E5%B9%B4%E5%85%AD%E6%9C%88%E6%A2%A6%E8%AE%B0/</link>
<guid>https://blog.southfox.me/2022/06/%E4%BA%8C%E4%BA%8C%E5%B9%B4%E5%85%AD%E6%9C%88%E6%A2%A6%E8%AE%B0/</guid>
<pubDate>Tue, 14 Jun 2022 18:09:34 GMT</pubDate>
<description>&lt;p&gt;能做梦说明我是终于有睡饱了……&lt;/p&gt;</description>
<content:encoded><![CDATA[<p>能做梦说明我是终于有睡饱了……</p><span id="more"></span><h2 id="6-14-中"><a href="#6-14-中" class="headerlink" title="6-14 中"></a>6-14 中</h2><h3 id="预兆"><a href="#预兆" class="headerlink" title="预兆"></a>预兆</h3><p>我在一个广场上,一些人就站在其中,广场中间有一个大号喷泉。<br>我跟着某个人去见……某个人……那个人一见我就立马用手搓着我的脸,我回应了几句,期间他嘴里漏出了几句中文。我问到,你懂中文?<br>他回应道:“我爷爷后半辈子在太原生活。”<br>然后他又仔细端详着我的脸,我说:“看相不应该是南方盛行的东西吗?”,他只打了个哈哈就应付过去了。看完相后,他拉着我走起了步伐,不像跳舞,像是……禹步?但是我还是有时像跳舞一样被他一手用手拉着。结束后,他大声疾呼:“大干旱,大旱灾之象啊!”,然后就跑开了。<br>我只觉得他的语言有点神经,八亿年之久的大干旱?比几百万年的卡尼期洪积事件还要离谱哩,望着广场喷涌的喷泉,我这样想到……</p><h3 id="干旱来临"><a href="#干旱来临" class="headerlink" title="干旱来临"></a>干旱来临</h3><p>随后就是旱灾来临了,倒是都是躺下的人,可能还有几个还能哀嚎,其他人已经毫无动静了……广场中间的喷泉早已干涸,或许只有中间的泥土还保有几丝湿润。喷泉中躺倒着一人,我望向他,就似乎看到了当时的景象——别死在喷泉里!会污染的!会污染的!滚出去……<br>我只想找到那个预言家,他去哪儿了?</p><h3 id="幕后"><a href="#幕后" class="headerlink" title="幕后"></a>幕后</h3><p>巨大的六角形机器浮在空中,然后一道细小的白光闪了出去,打向不远处的另一个六角形,但是一道强光爆发出来,把白光弹回了原六角形处……<br>一个类似控制式的地方……屏幕亮了起来。<br>“我们已知晓你所做的破坏活动!还接连破坏了七个地区……严惩……”<br>然后似乎被某人关掉了,那人连线上了另外一个人,另一个人似乎类似鳄鱼,但是脸确有像阶梯状,非常古怪。控制室内的人叫鳄鱼人把身份信息发过来好进行伪装,说是要这样才能糊弄过那些追查过来的人,看起来那鳄鱼人是什么纳税大户吗?</p>]]></content:encoded>
<category domain="https://blog.southfox.me/categories/%E6%A2%A6%E8%AE%B0/">梦记</category>
<category domain="https://blog.southfox.me/tags/%E6%A2%A6%E8%AE%B0/">梦记</category>
<comments>https://blog.southfox.me/2022/06/%E4%BA%8C%E4%BA%8C%E5%B9%B4%E5%85%AD%E6%9C%88%E6%A2%A6%E8%AE%B0/#disqus_thread</comments>
</item>
<item>
<title>Magit使用随记暨Emacs随记3</title>
<link>https://blog.southfox.me/2022/06/magit%E4%BD%BF%E7%94%A8%E9%9A%8F%E8%AE%B0%E6%9A%A8Emacs%E9%9A%8F%E8%AE%B0%EF%BC%883%EF%BC%89/</link>
<guid>https://blog.southfox.me/2022/06/magit%E4%BD%BF%E7%94%A8%E9%9A%8F%E8%AE%B0%E6%9A%A8Emacs%E9%9A%8F%E8%AE%B0%EF%BC%883%EF%BC%89/</guid>
<pubDate>Wed, 08 Jun 2022 14:38:26 GMT</pubDate>
<description>&lt;p&gt;&lt;code&gt;magit&lt;/code&gt; 是个好东西。&lt;/p&gt;</description>
<content:encoded><![CDATA[<p><code>magit</code> 是个好东西。</p><span id="more"></span><p><code>Magit</code> 是一个 <code>Emacs</code> 的包,将一大堆长又长的 <code>Git</code> 指令封装成了按键操作,对于受够了了在终端下按够了 <code>TAB</code> 键的人来说,是一种解放,无怪 <code>Magit</code> 的评价在整个 <code>Emacs</code> 生态里评价那么好了。</p><h2 id="Git"><a href="#Git" class="headerlink" title="Git"></a>Git</h2><p><code>Magit</code> 是建立在 <code>Git</code> 上的,意味着要使用得先对 <code>Git</code> 有一定了解,<a href="https://book.douban.com/subject/27133267/">Pro Git</a> 是一本不错的入门书,而且做为一本「开源」书籍,也很容易在网上找到可在线浏览的方式。</p><h3 id="奇怪比喻"><a href="#奇怪比喻" class="headerlink" title="奇怪比喻"></a>奇怪比喻</h3><p><code>Git</code> 的精髓在于它的设计,工作区、暂存区以及版本库,用 <code>Git</code> 进行工作一般如下所示(图出自 Pro Git。</p><p><img src="https://media.southfox.me/ipfs/bafkreidcpqxgpknpmc5nmtjqzulncjwfdauiorlt6lcggxfswjh36rjelq"></p><p>用小学生写作业做比喻的话,草稿纸即是工作区,做好相关计算后把结果誊抄到作业本上,作业本既是暂存区(<code>Index</code>、<code>Stage</code>),最后确认无误后即可把作业本放入书包,书包既是版本库了。</p><p><code>Git</code> 的设计给了使用者操作上的灵活,却也让人感到冗长,设置别名可以缓解这种情况,不过还是没有优化到单键操作的 <code>Magit</code> 偷懒偷得多。</p><h2 id="Magit"><a href="#Magit" class="headerlink" title="Magit"></a>Magit</h2><h3 id="一般流程"><a href="#一般流程" class="headerlink" title="一般流程"></a>一般流程</h3><p>在 <code>Doom Emacs</code> 下,使用 <code>SPC g g</code> 即可选择一个 <code>Git</code> 仓库(如果已经打开了一个 <code>Git</code> 仓库的的文件即可直接打开当前仓库下的 <code>Magit</code> 界面)打开 <code>Magit</code> 界面。</p><p><img src="https://media.southfox.me/ipfs/bafkreiele2ihm55y4rbemvz4dojlnukapibj4zn5isssj2x5huqsq76qdq"></p><p>在 <code>Magit</code> 界面下可以很方便看到工作区发生变动的文件Unstaged changes以及已经加入到暂存区的文件Staged changes。</p><p><img src="https://media.southfox.me/ipfs/bafkreicttv7rkuzq5ishn6x3lix4rwdtkka7dubm5rjh67teehgcbh7nzy"></p><p>光标在某个文件上时,按下 <code>TAB</code> 即可展示文件的变动,按下回车即可直接跳转到文件进行编辑,按下 <code>s</code> 即可将文件暂存,对处于暂存区文件按下 <code>u</code> 即可取消暂存(<code>S</code> 和 <code>U</code> 则是应用于全体文件)。忘掉 <code>git add xxx</code> 吧,谁会怀念它?</p><p>确认暂存区的改动后即可进行提交commit将其送入版本库了对应的快捷键是 <code>c</code>,对于很多复杂的 <code>Git</code> 操作附带了很多选项来完成,<code>Magit</code> 把能用的操作都罗列了出来,做到了看菜下饭。</p><p>对于提交commit 操作,其里面常用的有:</p><ul><li><code>- s</code> 或 <code>- S</code> 附上签名消息或使用 <code>GPG</code> 进行签名认证。</li><li><code>c</code> 进行 <code>commit</code> 操作,之后会打开一个新区域输入消息,输入完毕后用 <code>C-c C-c</code> 进行确认(<code>C-c C-k</code> 为取消提交)。</li><li><code>a</code> 进行 <code>--amend</code> 操作,即为重新进行提交操作,适用于提交完了才发现漏掉了几个文件没有添加,或者提交信息写错了的情况。</li></ul><p>实际用习惯了之后基本就是无脑操作了,比如使用 <code>p p</code> 快捷键,即可直接推送到默认的分支上,如果要进行其他操作比如推送到其他分支上,那么按一下 <code>p</code> 之后再看信息提示进行操作也不会太难。</p><p>对于更多操作,按下 <code>?</code> 即可进入提示菜单,或是翻阅 <code>Magit</code> 的<a href="https://magit.vc/manual/magit.html">手册</a>了解更多操作。</p><h3 id="从实战到跑路"><a href="#从实战到跑路" class="headerlink" title="从实战到跑路"></a>从实战到跑路</h3><p>现在来说说我拿 <code>Magit</code> 实际干过的事吧,</p><p>首先是要心动,看上了其他分支的功能,打算抄抄作业,那么第一件事就是把对方仓库克隆下来。在 <code>Magit</code> 界面按下 <code>M</code> 即可进入 <code>Remote</code> 界面,按下 <code>a</code> 添加,输入名称以及仓库地址来添加一个 <code>Remote</code> 。</p><p>接着开始检索对方仓库的提交,检出自己需要的提交,按下 <code>l</code> 打开 <code>log</code> 界面,按下 <code>- F</code> 搜索提交消息,之后输入想检索的提交消息,例如 <code>exclusive list</code>,再按下 <code>o</code> 选择搜索其他other分支的历史记录选择之前添加的 <code>Remote</code> 仓库的分支。</p><p><img src="https://media.southfox.me/ipfs/bafkreiduuqcpezsvunsggij4gfahdn53kxiacwewsbmciglk62v44yoane"></p><p>可以看到搜索出了相关的三条结果,从最旧的开始合并,将光标移动到最旧的提交,按下 <code>A A</code> 进行一次 <code>cherry-pick</code> 。</p><p><img src="https://media.southfox.me/ipfs/bafkreifkslyzgyvcm5zkapevoxkrnkdubh7uwbwwjjpjrkmwur43k4ji7i"></p><p>啊啊啊……!一大堆冲突,毕竟这次的提交很老旧了,是三年前的提交,发生变化很正常……</p><p>感叹一句没有银弹,<code>Git</code> 对于冲突也从不僭越,会去自作主张搞定。所以只能自己上了,对于这种老旧的提交,可以前去 <code>GitHub</code> 的那次提交消息里查看改动了哪些文件,再前去最新版本文件下仔细比对最新的样子是什么。当然 <code>Magit</code> 同时也提供了一个命令 <code>magit-log-buffer-file</code><code>SPC g L</code>)查看当前文件下有那些提交,</p><p><img src="https://media.southfox.me/ipfs/bafkreied5lnnuofc7isxw3ufrg6j7gbs4ptzs27pkuxq54tcicnltl3k5e" alt="检出更改"></p><p>不过用这种方式查看双方提交记录的话,得先 <code>Stash</code> 修改再切换到对方分支查看历史记录又切换回来,感觉挺麻烦……所以我就先用 <code>GitHub</code> 查看历史了,或许有更快速方便的方法?</p><p>总之,确定该怎样合并后即可进入 <code>Unstaged changes</code> 上的任一文件按下 <code>E</code> 打开 <code>Ediff</code> 选单,再按下 <code>m</code> 解决冲突。</p><p><img src="https://media.southfox.me/ipfs/bafkreie5it6wivelcnp63l34epa377lijrksptmodz7nwsb7325n4g4zsq"></p><p>进入冲突选单后,用 <code>n</code> 键跳转到下一冲突处(<code>p</code> 为上一个),接着按下 <code>a</code> 或 <code>b</code> 选择保留那一方的修改,这次的提交要结合两者,所以首先选择一方,然后用 <code>SPC w k</code> 将焦点移动到上方文件编辑区进行编辑,编辑完后再用 <code>SPC w j</code> 将焦点移回 <code>Ediff</code> 区。处理完全部冲突后,按下 <code>q</code> 退出,再处理其他文件的冲突。</p><p>处理完全部冲突后,按下 <code>c c</code> 进行一次提交,之后按下 <code>p p</code> 推送到 <code>GitHub</code> 上,祈祷部署能够成功吧!</p><p>如果想要合并的提交不是那么久远的话,可以用 <code>Y</code> 按键对应的 <code>Cherries</code> 操作来检出自己想要的提交,虽然我没用过(</p>]]></content:encoded>
<category domain="https://blog.southfox.me/categories/%E6%8A%80%E6%9C%AF/">技术</category>
<category domain="https://blog.southfox.me/tags/Emacs/">Emacs</category>
<category domain="https://blog.southfox.me/tags/Git/">Git</category>
<comments>https://blog.southfox.me/2022/06/magit%E4%BD%BF%E7%94%A8%E9%9A%8F%E8%AE%B0%E6%9A%A8Emacs%E9%9A%8F%E8%AE%B0%EF%BC%883%EF%BC%89/#disqus_thread</comments>
</item>
<item>
<title>我拿Emacs做什么暨Emacs随记2</title>
<link>https://blog.southfox.me/2022/05/%E6%88%91%E6%8B%BFEmacs%E5%81%9A%E4%BB%80%E4%B9%88%E6%9A%A8Emacs%E9%9A%8F%E8%AE%B0%EF%BC%882%EF%BC%89/</link>
<guid>https://blog.southfox.me/2022/05/%E6%88%91%E6%8B%BFEmacs%E5%81%9A%E4%BB%80%E4%B9%88%E6%9A%A8Emacs%E9%9A%8F%E8%AE%B0%EF%BC%882%EF%BC%89/</guid>
<pubDate>Sat, 14 May 2022 17:34:55 GMT</pubDate>
<description>&lt;p&gt;大概也算是卡片笔记法的介绍?&lt;/p&gt;</description>
<content:encoded><![CDATA[<p>大概也算是卡片笔记法的介绍?</p><span id="more"></span><blockquote><p><strong>提醒</strong>:本文作者用上下列的方法也不是很久,甚至这篇文章还能算做第一个正式产出,所以……请谨慎判断。</p></blockquote><h2 id="卡片笔记"><a href="#卡片笔记" class="headerlink" title="卡片笔记"></a>卡片笔记</h2><h3 id="卡片笔记法解决了什么?"><a href="#卡片笔记法解决了什么?" class="headerlink" title="卡片笔记法解决了什么?"></a>卡片笔记法解决了什么?</h3><p>在空白处写涂涂写写、划重点、摘抄、不断翻阅资料,但是最后感觉还是学废了,到头来还是什么也没学到,或者记了一大堆笔记但是却成了一个坟墓,每次到里面想要提取点东西简直痛不欲生……</p><p>因为不断的阅读书籍并没有对学习产生帮助,反而因为<strong>曝光效应</strong>而更有害(曝光效应:当我们熟悉某事物的时候,我们还会对其越发喜欢,相信自己理解了,<strong>但是熟悉不等同于理解</strong>)。</p><p>卡片笔记法就是针对这种情况而产生的。</p><h3 id="卡片笔记法该怎么做?"><a href="#卡片笔记法该怎么做?" class="headerlink" title="卡片笔记法该怎么做?"></a>卡片笔记法该怎么做?</h3><p>我目前所使用的工作流是这样的:</p><ul><li>阅读材料,写下关键词或者想法和页数。(闪念笔记)</li><li>结束阅读后,通过关键词重构当时的话语,并通过页数返回当时的段落,对照着材料<strong>转写</strong>成自己的话语录入到笔记系统中。(文献笔记)</li><li>当天结束前,浏览自己的所写的文献笔记,思考它能和自己的课题、兴趣、兴趣有何关联。(永久笔记)</li></ul><h4 id="闪念笔记"><a href="#闪念笔记" class="headerlink" title="闪念笔记"></a>闪念笔记</h4><p>闪念笔记可以……在任何地方开记,餐巾纸、手机、记事本等,只是写下几个关键字而已,并标上页数,结束完阅读后,再通过关键词思索当时的想法,之后通过页数方便返回对照材料。</p><p>此举是为了增加想法的<strong>必要难度</strong>,边阅读、边听课、边看视频边记笔记实在太简单,就像在沙地上浅浅地写字一样,太容易模糊了……而通过记下关键词和页数,再回忆起当时所想记的,这样(大概)就提升了想法的<strong>存储强度</strong>。</p><h4 id="文献笔记"><a href="#文献笔记" class="headerlink" title="文献笔记"></a>文献笔记</h4><p>文献笔记最重要的是用<strong>自己的话</strong>简洁得写下阅读材料中的观点。</p><p>之所以强迫用自己的话转写,是因为只有这样做才能更好地理解材料里的观点,一味摘抄是不行的……</p><h4 id="永久笔记"><a href="#永久笔记" class="headerlink" title="永久笔记"></a>永久笔记</h4><p>永久笔记是通过浏览前几步写下的笔记所产生的,卡片笔记盒的思想就是:</p><blockquote><p>一个想法或者笔记只有在它的上下文才有意义,而它的上下文不一定是它在文章中的出处。所以卡片笔记法是要让笔记与不同上下文聚集起来并起到相应的作用。</p></blockquote><p>其中永久笔记应该是<strong>原子化</strong>的,即应该在没有上下文的情况下也能解释的清楚,这样才能更好的和其他相同的笔记组合成「分子」、「复杂化合物」。</p><p>所以为了更好地产生想法,每天划出一部分时间是去回顾是必要的(当然我也老是忘掉)。</p><h3 id="Carry-on"><a href="#Carry-on" class="headerlink" title="Carry on!"></a>Carry on!</h3><blockquote><p>简单,简单,简单啊!我说,最好你的事只两件或三件,不要一百件或一千件;不必计算一百万,半打不是够计算了吗,总之,账目可以记在大拇指甲上就好了。不必一天三餐,如果必要,一顿也够了;不要百道菜,五道够多了; 《瓦尔登湖》</p></blockquote><p>卡片笔记法并不复杂,实践起来只要选用一个专门对此进行优化过的软件就好了,<code>Notion</code>、<code>obsidian</code>、<code>org-roam</code> 等都可以,我选用的是基于 <code>Emacs</code> 的 <code>org-roam</code> 。</p><p>过于复杂的工作流会马上消磨掉自己的耐心,而做事从来不能凭着虚无缥缈的「专注力」去完成,同时卡片笔记法所产生的笔记也让我觉得能在实实在在的做了某事,这样在对抗「不确定性」这一大怪兽面前也能有底气几分。</p><p>卡片笔记法也不是什么银弹,不能指望换用软件就能产生很好的效果,比如说卡片笔记法里重要的一点既是用自己的话去转写阅读材料的话语,没了解这一点,换软件后还把软件当成原文摘抄、文章剪辑之地,那么无非是又造了个坟墓,只不过是卡片式的。</p><h2 id="任务管理"><a href="#任务管理" class="headerlink" title="任务管理"></a>任务管理</h2><p>任务管理也是我拿 <code>Emacs</code> 所做的事,并且他的表现也比较优秀,稍微设置一些模板就能表现的很好。</p><h3 id="番茄工作法"><a href="#番茄工作法" class="headerlink" title="番茄工作法"></a>番茄工作法</h3><p>番茄工作法,即在做事时划分一段专门用来做<strong>一件事</strong>的时间,期间不允许做其他事,以期达到更好的做事效果。</p><h3 id="蔡格尼克效应"><a href="#蔡格尼克效应" class="headerlink" title="蔡格尼克效应"></a>蔡格尼克效应</h3><p>蔡格尼克走近一家餐馆,发现服务员游刃有余得在多个顾客间间穿梭并记下点单且上菜,吃罢饭后,蔡格尼特发现忘记取大衣并折返,还想顺道称赞一下服务员的能力,但她惊讶的发现服务员竟然表示完全不记得她来过了!服务员表示干这一行的都把注意力集中在点单上面了……</p><p>蔡格尼特对此事做了研究发现:</p><blockquote><p>相较于已经完成的工作,人们比较容易记得未完成的,或是被打断的工作。这就是为什么我们的注意力很容易被未完成任务的想法所干扰,而不管这些想法的重要性如何。得益于蔡格尼克的后续研究,我们还知道,其实我们并不一定要完成任务才能说服我们的大脑停止思考它们,我们所要做的就是把想法写下来,让大脑相信它会在之后被妥善处理。至于任务是真的被完成了,还是通过记下笔记而推迟了,大脑并不会区分。</p></blockquote><h3 id="Just-do-it"><a href="#Just-do-it" class="headerlink" title="Just do it!"></a>Just do it!</h3><p>而具体的工作流,就是我会专门在一天的开始的时候,通常是泡咖啡的时候打开电脑,开始把今天要干的麻烦事写下来(我同时也把 <code>Emacs</code> 设置成开机启动了,打开电脑就是打开 <code>Emacs</code>)。等到有晚上有时间了,我会把想做的事进行分解,以期降低自己的抵抗心理(例如<code>写一篇文章</code>的任务看起来太困难了,但把它分解成<code>收集材料</code>、<code>思考结构</code>、<code>完成初稿</code>等就容易一点了)。</p><h2 id="Emacs"><a href="#Emacs" class="headerlink" title="Emacs"></a>Emacs</h2><p>啊,甜美的 <code>Emacs</code> 。</p><h3 id="org-roam"><a href="#org-roam" class="headerlink" title="org-roam"></a>org-roam</h3><h4 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h4><p>安装很简单,在配置文件中 <code>~/.doom.d/init.el</code> 中的 <code>org</code> 模块里加上 <code>roam2</code> 再 <code>sync</code> 一下就好了。</p><figure class="highlight lisp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">(<span class="name">org</span></span><br><span class="line"> +roam2) <span class="comment">; organize your plain life in plain text</span></span><br></pre></td></tr></table></figure><h4 id="配置"><a href="#配置" class="headerlink" title="配置"></a>配置</h4><figure class="highlight lisp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">;; org-roam</span></span><br><span class="line">(<span class="name">setq</span> org-roam-directory <span class="string">&quot;~/Nextcloud/Note/org-roam&quot;</span>)</span><br><span class="line">(<span class="name">setq</span> org-roam-capture-templates</span><br><span class="line"> &#x27;((<span class="string">&quot;m&quot;</span> <span class="string">&quot;main&quot;</span> plain</span><br><span class="line"> <span class="string">&quot;%?&quot;</span></span><br><span class="line"> :if-new (file+head <span class="string">&quot;main/$&#123;slug&#125;.org&quot;</span></span><br><span class="line"> <span class="string">&quot;#+title: $&#123;title&#125;\n&quot;</span>)</span><br><span class="line"> :immediate-finish <span class="literal">t</span></span><br><span class="line"> :unnarrowed <span class="literal">t</span>)</span><br><span class="line"> (<span class="string">&quot;r&quot;</span> <span class="string">&quot;reference&quot;</span> plain <span class="string">&quot;%?&quot;</span></span><br><span class="line"> :if-new</span><br><span class="line"> (file+head <span class="string">&quot;reference/$&#123;title&#125;.org&quot;</span> <span class="string">&quot;#+title: $&#123;title&#125;\n&quot;</span>)</span><br><span class="line"> :immediate-finish <span class="literal">t</span></span><br><span class="line"> :unnarrowed <span class="literal">t</span>)</span><br><span class="line"> (<span class="string">&quot;a&quot;</span> <span class="string">&quot;article&quot;</span> plain <span class="string">&quot;%?&quot;</span></span><br><span class="line"> :if-new</span><br><span class="line"> (file+head <span class="string">&quot;articles/$&#123;title&#125;.org&quot;</span> <span class="string">&quot;#+title: $&#123;title&#125;\n#+filetags: :article:\n&quot;</span>)</span><br><span class="line"> :immediate-finish <span class="literal">t</span></span><br><span class="line"> :unnarrowed <span class="literal">t</span>)))</span><br></pre></td></tr></table></figure><p>其中 <code>org-roam-directory</code> 是放置笔记文件的路径,我把它设置到了 <code>Nextcloud</code> 的同步目录下,这样换台电脑也能快速查看笔记。</p><p>而 <code>org-roam-capture-templates</code> 是配置笔记的模板,<code>main</code> 是对应的是 <code>永久笔记</code><code>reference</code> 对应的是 <code>文献笔记</code><code>article</code> 可以对应的产出文章,虽然我这篇是直接在博客文件夹下写的(</p><h4 id="具体使用"><a href="#具体使用" class="headerlink" title="具体使用"></a>具体使用</h4><p>经过模板配置后,按下 <code>SPC n r f</code> 输入一个不存在的标题就是新建一个笔记了,再按下提前配置好的键指定是哪类笔记。</p><p>按下 <code>SPC n r i</code> 既是在正文中插入一条笔记链接,<code>SPC n r r</code> 既是打开显示双向链接的菜单,能帮助我更好地查看笔记之间的联系。</p><p>而通过 <code>SPC n r a</code> 即可随机跳转到一条笔记上方便我回顾笔记可惜我太菜了不知道怎么设置成过滤成只显示仅某一类笔记orz。</p><p>同时 <code>org-roam</code> 里还附带了一个日志功能,可以像 <code>Logseq</code> 那样写日志,其前缀是 <code>SPC n r d</code>,但由于太长我一般都是通过 <code>M-x</code> 来进行选择对应功能的,现在我的一些想法和梦记都是录入到其中的。</p><p>而对于文献笔记,因为没琢磨透 <code>Emacs</code> 相关文献管理包怎么用,那我就用自带的大纲模式进行折腾了,具体就是用各个标题层级对应书的不同目录,并在最后加上页码,这样也方便我进行回读。</p><p><img src="https://media.southfox.me/ipfs/bafkreidapw5bcu6ix2nxxi7uhbaiwnc23nukqfyzububigmk4hfcancc3u"></p><h4 id="连接"><a href="#连接" class="headerlink" title="连接"></a>连接</h4><p><code>org-roam</code> 第 2 个大版本将里面的链接机制换成了基于 <code>org-mode</code> 的 <code>link</code>,所以让 <code>org-roam</code> 有了跟其他基于文章的双链笔记不同的,有更加精细的操控能力了。</p><p>在某个标题使用 <code>org-id-get-creat</code> 就可以把这个标题转换为一个新的卡片笔记了,既使它仍在一篇文章中,这样一篇挤满不同卡片的文件我可以叫他为 <code>卡片桌</code>,可以方便的排列展示各个卡片笔记。</p><p>而把 <code>org-link-search-must-match-exact-headline</code> 的值设置成 <code>nil</code>,那么可以编辑链接,设成 <code>[[roam-id:xxx-xxx-xxx-xxx::关键字][描述文本]]</code> 即自动跳转到所选笔记的第一个匹配关键词上,不得不感叹 <code>Emacs</code> 对于文字处理的底蕴之深……</p><h4 id="加密"><a href="#加密" class="headerlink" title="加密"></a>加密</h4><p>选择了同步意味数据会放到他人的服务器上,所以一些东西不加密实在不放心,所幸其自带了一个包 <code>epa</code> 可以完成加密工作,或是在模板中设置成 <code>xxx.org.gpg</code> 格式就会自动进行加密……当然因为加密设定必须要设置一个同步密钥,对于互相连接的卡片笔记非常不方便(一打开菜单输入四五次加密密码谁受得了啊),所幸其 <code>epa</code> 包里有仅加密一片文本区域的命令 <code>epa-encrypt-region</code>,事先选择好一片文本区域执行此命令,再指定密码即可执行加密了。</p><h4 id="MORE"><a href="#MORE" class="headerlink" title="MORE!"></a>MORE!</h4><p>当然还有其他的扩展包可以用,比如 <code>org roam ui</code>,这个包可以分析笔记文件形成一个网页,让 <code>Emacs</code> 用户也能享受到其他双链笔记软件的那个「花里胡哨」的链接分析图。</p><p><img src="https://media.southfox.me/ipfs/bafkreicodyiisf7hstovxpkw5excjlmdltlxgjjqbvsghrhmrfxc5hrytm"></p><h3 id="任务管理-1"><a href="#任务管理-1" class="headerlink" title="任务管理"></a>任务管理</h3><p><code>Emacs</code> 自带了个 <code>org-mode</code>,是做任务管理的一把好手,当然要提前配置好任务模板。</p><h4 id="任务模板"><a href="#任务模板" class="headerlink" title="任务模板"></a>任务模板</h4><figure class="highlight lisp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">;; org-capture</span></span><br><span class="line">(<span class="name">setq</span> org-agenda-files &#x27;(<span class="string">&quot;~/Nextcloud/gtd/inbox.org&quot;</span></span><br><span class="line"> <span class="string">&quot;~/Nextcloud/gtd/gtd.org&quot;</span></span><br><span class="line"> <span class="string">&quot;~/Nextcloud/gtd/tickler.org&quot;</span>))</span><br><span class="line"></span><br><span class="line">(<span class="name">after!</span> org</span><br><span class="line"> (<span class="name">setq</span> org-capture-templates &#x27;((<span class="string">&quot;t&quot;</span> <span class="string">&quot;Todo [inbox]&quot;</span> entry</span><br><span class="line"> (file+weektree <span class="string">&quot;~/Nextcloud/gtd/inbox.org&quot;</span>)</span><br><span class="line"> <span class="string">&quot;* TODO %i%?&quot;</span>)</span><br><span class="line"> (<span class="string">&quot;T&quot;</span> <span class="string">&quot;Tickler&quot;</span> entry</span><br><span class="line"> (file+headline <span class="string">&quot;~/Nextcloud/gtd/tickler.org&quot;</span> <span class="string">&quot;Tickler&quot;</span>)</span><br><span class="line"> <span class="string">&quot;* %i%? \n %U&quot;</span>))))</span><br></pre></td></tr></table></figure><p>其中 <code>org-agenda-file</code> 是设置将哪些文件拉入到日历视图的计算中,<code>org-agenda</code> 视图可以很方便地查看任务分布情况,当然可设可不设。<br><code>org-capture-templates</code> 是设置任务模板,要用 <code>after!</code> 关键字括起来用延后加载以免被默认配置覆盖掉,其中我将 <code>Todo</code> 的格式设成了 <code>weektree</code> 的格式,这会将任务归类成 <code>年-XX周-星期X</code> 的格式,方便进行定位以及用 <code>org-archive-subtree</code> 的命令将已完成的任务存档。<br>更多关于任务模板的相关介绍可看<a href="https://www.zmonster.me/2018/02/28/org-mode-capture.html">这里</a>。</p><h4 id="使用"><a href="#使用" class="headerlink" title="使用"></a>使用</h4><p>这样配置下来,使用 <code>SPC X</code> 即可打开一个缓冲,按下 <code>t</code> 即可选择预先配置的 <code>Todo</code> 模板,接下来输入任务名称,按下 <code>C-c C-c</code> 即可将缓冲中的内容送入文件,同时关闭缓存。这个过程不需要去打开其他文件,适合在一个工作流中突然想起某事而花最小的打断代价去写下代办事项。</p><h4 id="移动端使用"><a href="#移动端使用" class="headerlink" title="移动端使用"></a>移动端使用</h4><p>目前我在安卓端上使用的是 <code>[Orgzly](https://f-droid.org/packages/com.orgzly/)</code> 搭配 <code>Nextcloud</code> 进行任务同步,利用小组件功能也能方便一览待办(就是小组件的刷新是个问题)。</p><h3 id="番茄钟"><a href="#番茄钟" class="headerlink" title="番茄钟"></a>番茄钟</h3><h4 id="安装-1"><a href="#安装-1" class="headerlink" title="安装"></a>安装</h4><p>在 <code>~/.doom.d/init.el</code> 中加上 <code>pomodoro</code> 即可。</p><figure class="highlight lisp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">(<span class="name">org</span></span><br><span class="line"> +roam2</span><br><span class="line"> +pomodoro) <span class="comment">; organize your plain life in plain text</span></span><br></pre></td></tr></table></figure><h4 id="使用-1"><a href="#使用-1" class="headerlink" title="使用"></a>使用</h4><p>在一个待办标题上使用 <code>SPC t t</code> 即可开启番茄计时,默认二十五分钟倒计时,还附带一个有点浮夸的敲钟音效(</p><p><img src="https://media.southfox.me/ipfs/bafkreieirqmdin4xhx57druv47vt64goyjbohwbumuahq5z5xg3y7bjxke"></p><h2 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h2><ol><li><a href="https://jethrokuan.github.io/org-roam-guide/">How I Take Notes with Org-roam</a></li><li>卡片笔记写作法:如何实现从阅读到写作</li><li><a href="https://mp.weixin.qq.com/s/jM6OoQLxKE4dT_ZWLibowA">用“卡片笔记写作法”读《卡片笔记写作法》 译者现身说法并完整示范 | 学习骇客 </a> </li><li><a href="https://www.zmonster.me/2018/02/28/org-mode-capture.html">强大的 Org mode(4): 使用 capture 功能快速记录</a></li></ol>]]></content:encoded>
<category domain="https://blog.southfox.me/categories/%E6%8A%80%E6%9C%AF/">技术</category>
<category domain="https://blog.southfox.me/tags/Emacs/">Emacs</category>
<category domain="https://blog.southfox.me/tags/%E9%9A%8F%E8%AE%B0/">随记</category>
<comments>https://blog.southfox.me/2022/05/%E6%88%91%E6%8B%BFEmacs%E5%81%9A%E4%BB%80%E4%B9%88%E6%9A%A8Emacs%E9%9A%8F%E8%AE%B0%EF%BC%882%EF%BC%89/#disqus_thread</comments>
</item>
<item>
<title>Emacs随记1</title>
<link>https://blog.southfox.me/2022/04/Emacs%E9%9A%8F%E8%AE%B0%EF%BC%881%EF%BC%89/</link>
<guid>https://blog.southfox.me/2022/04/Emacs%E9%9A%8F%E8%AE%B0%EF%BC%881%EF%BC%89/</guid>
<pubDate>Tue, 19 Apr 2022 13:09:05 GMT</pubDate>
<description>&lt;p&gt;小心,传教士来了.jpg&lt;/p&gt;</description>
<content:encoded><![CDATA[<p>小心,传教士来了.jpg</p><span id="more"></span><p><code>Emacs</code>,一款诞生于 <code>1975</code> 年的开源软件,时间并没有葬送这款软件,直至现在也依然也有不少“奇怪”的人在日常使用它。</p><h2 id="Why"><a href="#Why" class="headerlink" title="Why?"></a>Why?</h2><p>讲为什么要使用 <code>Emacs</code> 不如先讲讲为什么不用 <code>Emacs</code>。</p><ul><li>它对 <code>Win</code> 系统支持不是很友好</li><li>全按键操作很劝退从微机课学起电脑的“现代”信息原住民</li><li>如果说 <code>Vim</code> 是小众编辑器,那么 <code>Emacs</code> 更是小众中的小众,导致很多东西都要自己去翻找</li><li>经常出现一些让人恼火的小问题,结合上点更让人吐血</li></ul><p>还不够劝退吗?那为什么我还要用 <code>Emacs</code> 呢?</p><ul><li>它的内存占用4G 的电脑也带的动,我是受够了套壳框架带来的吃内存大户了……浏览器 + <code>VS Code</code> 已经挤得我电脑动弹不得了。</li><li>它的哲学,如果说 <code>Linux</code> 的哲学是一切皆文件,那么 <code>Emacs</code> 的哲学就是对于文本的操控了,将电子邮件导入到待办事项,把即时通讯里的通天记录裁剪到收藏里,就连近些火热的双链也有人去实现……因为这些都是“文本”,所以他们就可以被 <code>Emacs</code> 各个包处理。这些功能要让其他软件去实现,非得用上不同软件拼凑不可,同时他们之间的联系也很脆弱,全看软件开发者是否开放……</li><li>它的智慧,虽然我现在也是摸索着用了一段时间,到现在也才是打开次数跟 <code>VS Code</code> 持平的状态,不过我也足以感受到其中的“智慧”了,它确实很适合培养所谓的“计算机素养”,哪怕用它的人中很多并不是程序员。</li></ul><h2 id="Why-Doom-Emacs"><a href="#Why-Doom-Emacs" class="headerlink" title="Why Doom Emacs"></a>Why Doom Emacs</h2><p>现在我在用的是 <a href="https://github.com/hlissner/doom-emacs">Doom Emacs</a> ,他们之间的关系有点像是 <code>Minecraft</code> 和 <code>整合包</code> 之间的关系,原版生存固然足够好玩且富有深度了,但还是太朴素了,想弄点更大的乐子那自然是往里灌上一众 <code>MOD</code> 了。而配好一整套相关 <code>MOD</code> 的即是整合包了,<code>Doom Emacs</code> 在各种配置整合包里算得上是高效和……轻量?(毕竟我也没用过其他的配置)</p><p>同时其中还附带了 <code>evil</code> 这个包,可以让 <code>Emacs</code> 用上 <code>Vim</code> 的操作,想想这确实挺“邪恶”,<code>Emacs</code> 和 <code>Vim</code> 之间的“圣战”一直打得昏天暗地,谁知其中竟然分裂出一个教派结合了两方?也确实不愧于 <code>Doom</code> 之名啊……</p><p>能蹭上 <code>Vim</code> 的操作也是好事,因为 <code>Vim</code> 的相关资料比 <code>Emacs</code> 多上许多,比较好找到相关资料,也避免了 <a href="https://zh.wikipedia.org/zh-hans/Emacs#Emacs%E5%B0%8F%E6%8B%87%E6%8C%87">Emacs 小拇指</a>症状。</p><h3 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h3><p><code>Emacs</code> 在各种 <code>Linux</code> 发行版自带的包管理应该能轻松找到(<code>Mac OS</code> 应该也能简单安装到),安装后运行一次就会生成 <code>~/.emacs.d</code> 路径下的文件夹。</p><p>确认文件夹存在后运行:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">git clone --depth 1 https://github.com/hlissner/doom-emacs ~/.emacs.d</span><br><span class="line"></span><br><span class="line">~/.emacs.d/bin/doom install</span><br></pre></td></tr></table></figure><p>其中安装会到 <code>GitHub</code> 下载一两百个包,所以提前配置好一个科学网络环境是必须的……</p><p>安装结束后,运行后并且……!</p><h3 id="存活下来"><a href="#存活下来" class="headerlink" title="存活下来"></a>存活下来</h3><h4 id="按键缩写"><a href="#按键缩写" class="headerlink" title="按键缩写"></a>按键缩写</h4><p>大部分资料都遵循以下缩写——</p><table><thead><tr><th>Emacs 功能键</th><th>缩写</th><th>对应键盘按键(PC&#x2F;Mac)</th></tr></thead><tbody><tr><td>Space</td><td>Spc</td><td>Space(空格)</td></tr><tr><td>Control</td><td>C</td><td>Ctrl &#x2F; Control</td></tr><tr><td>Meta</td><td>M</td><td>Alt &#x2F; Option</td></tr><tr><td>Shift</td><td>S</td><td>Shift &#x2F; Shift</td></tr></tbody></table><p>例如:</p><p> <code>Spc .</code> 是先按下 <code>空格</code> 键<strong>再</strong>按下 <code>.</code> 键。</p><p><code>M-x</code> 是按下 <code>Alt</code> 键<strong>同时</strong>按下 <code>x</code> 键。</p><h4 id="实际操作"><a href="#实际操作" class="headerlink" title="实际操作"></a>实际操作</h4><p>对于入门而言,使用 <code>S .</code> 即可打开文件管理,之后就可以选择一个文件进行打开了。</p><p><code>Vim</code> 编辑模式可能对于入门来说也是有点痛苦,不过初始时掌握 <code>i</code> 和 <code>:w</code> 也够用了。</p><p>不用特地去记快捷键,使用 <code>M-x</code> 搜索相应的命令大部分足够了,当知道自己在高频使用某个命令,那么这时候才稍微用一下快捷键并记忆就足够了。</p><p>找到自己想要的功能用兴趣做导向是最优的,<code>org-mode</code> 就是个不错的选择。</p><h4 id="参考教程"><a href="#参考教程" class="headerlink" title="参考教程"></a>参考教程</h4><p><a href="https://github.com/overmind1980/oeasyvim">Vim 教程 - Oeasy</a></p><p><a href="https://www.youtube.com/playlist?list=PLhXZp00uXBk4np17N39WvB80zgxlZfVwj">Doom Emacs 视频教程 - Zaiste Programming</a> <a href="https://space.bilibili.com/432142040/channel/seriesdetail?sid=432482">B 站搬运</a></p><p><a href="https://github.com/redguardtoo/mastering-emacs-in-one-year-guide/blob/master/guide-zh.org">一年成为Emacs高手 (像神一样使用编辑器)</a></p><p><a href="https://manateelazycat.github.io/emacs/2018/12/11/study-emacs.html">怎么学习 Emacs ? 达到真正融汇贯通的境界? </a></p><h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p>先写成这样吧,下篇大概会写点 <code>org-roam</code> 和 <code>org-mode</code> 相关配置……不过也得等我自己先折腾了,有东西能写了才能写……</p>]]></content:encoded>
<category domain="https://blog.southfox.me/categories/%E6%8A%80%E6%9C%AF/">技术</category>
<category domain="https://blog.southfox.me/tags/Emacs/">Emacs</category>
<comments>https://blog.southfox.me/2022/04/Emacs%E9%9A%8F%E8%AE%B0%EF%BC%881%EF%BC%89/#disqus_thread</comments>
</item>
<item>
<title>搭建Matrix即时通信服务</title>
<link>https://blog.southfox.me/2022/04/%E6%90%AD%E5%BB%BAMatrix%E5%8D%B3%E6%97%B6%E9%80%9A%E4%BF%A1%E6%9C%8D%E5%8A%A1/</link>
<guid>https://blog.southfox.me/2022/04/%E6%90%AD%E5%BB%BAMatrix%E5%8D%B3%E6%97%B6%E9%80%9A%E4%BF%A1%E6%9C%8D%E5%8A%A1/</guid>
<pubDate>Fri, 15 Apr 2022 20:54:19 GMT</pubDate>
<description>&lt;p&gt;总之稍微记录一下。&lt;/p&gt;</description>
<content:encoded><![CDATA[<p>总之稍微记录一下。</p><span id="more"></span><ul><li><p>事先约定 <code>matrix.org</code> 是前端地址 <code>synapse.matrix.org</code> 是后端地址,实际请改成自己的……具体为啥这么做可以看<a href="https://matrix-org.github.io/synapse/latest/delegate.html">官方文档</a>,如果嫌麻烦也可以不启用这功能……</p></li><li><p>新建文件夹,在里面新建一个 <code>docker-compose.yml</code> 文件,往里写入</p></li></ul><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#也感谢糖喵提供的配置文件~</span></span><br><span class="line"><span class="attr">version:</span> <span class="string">&quot;3.4&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="attr">services:</span></span><br><span class="line"> <span class="attr">synapse:</span></span><br><span class="line"> <span class="attr">hostname:</span> <span class="string">matrix</span></span><br><span class="line"> <span class="attr">image:</span> <span class="string">matrixdotorg/synapse:latest</span></span><br><span class="line"> <span class="attr">restart:</span> <span class="string">always</span></span><br><span class="line"> <span class="attr">container_name:</span> <span class="string">matrix_server</span> </span><br><span class="line"> <span class="attr">depends_on:</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">db</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">redis</span></span><br><span class="line"> <span class="attr">ports:</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">&quot;127.0.0.1:8001:8008&quot;</span></span><br><span class="line"> <span class="attr">volumes:</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">./synapse/data:/data</span></span><br><span class="line"> <span class="attr">networks:</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">synapse_network</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">external_network</span></span><br><span class="line"> <span class="attr">healthcheck:</span></span><br><span class="line"> <span class="attr">test:</span> [<span class="string">&quot;CMD-SHELL&quot;</span>, <span class="string">&quot;curl -s localhost:8008/health || exit 1&quot;</span>]</span><br><span class="line"></span><br><span class="line"> <span class="attr">db:</span></span><br><span class="line"> <span class="attr">image:</span> <span class="string">postgres</span></span><br><span class="line"> <span class="attr">restart:</span> <span class="string">always</span></span><br><span class="line"> <span class="attr">container_name:</span> <span class="string">matrix_db</span></span><br><span class="line"> <span class="attr">volumes:</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">./synapse/db:/var/lib/postgresql/data</span></span><br><span class="line"> <span class="attr">environment:</span></span><br><span class="line"> <span class="attr">POSTGRES_USER:</span> <span class="string">synapse</span></span><br><span class="line"> <span class="attr">POSTGRES_PASSWORD:</span> <span class="string">随便什么密码</span></span><br><span class="line"> <span class="attr">POSTGRES_DB:</span> <span class="string">synapse</span></span><br><span class="line"> <span class="attr">POSTGRES_INITDB_ARGS:</span> <span class="string">&quot;--encoding=&#x27;UTF8&#x27; --lc-collate=&#x27;C&#x27; --lc-ctype=&#x27;C&#x27;&quot;</span></span><br><span class="line"> <span class="attr">networks:</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">synapse_network</span></span><br><span class="line"> <span class="attr">healthcheck:</span></span><br><span class="line"> <span class="attr">test:</span> [<span class="string">&quot;CMD&quot;</span>, <span class="string">&quot;pg_isready&quot;</span>, <span class="string">&quot;-U&quot;</span>, <span class="string">&quot;synapse&quot;</span>]</span><br><span class="line"></span><br><span class="line"> <span class="attr">redis:</span></span><br><span class="line"> <span class="attr">image:</span> <span class="string">redis:6.0-alpine</span></span><br><span class="line"> <span class="attr">restart:</span> <span class="string">always</span></span><br><span class="line"> <span class="attr">container_name:</span> <span class="string">matrix_redis</span> </span><br><span class="line"> <span class="attr">volumes:</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">./synapse/redis:/data</span></span><br><span class="line"> <span class="attr">networks:</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">synapse_network</span></span><br><span class="line"> <span class="attr">healthcheck:</span></span><br><span class="line"> <span class="attr">test:</span> [<span class="string">&quot;CMD&quot;</span>, <span class="string">&quot;redis-cli&quot;</span>, <span class="string">&quot;ping&quot;</span>]</span><br><span class="line"></span><br><span class="line"><span class="attr">networks:</span></span><br><span class="line"> <span class="attr">synapse_network:</span></span><br><span class="line"> <span class="attr">internal:</span> <span class="literal">true</span></span><br><span class="line"> <span class="attr">external_network:</span></span><br></pre></td></tr></table></figure><ul><li>之后运行 <code>docker-compose run --rm -e SYNAPSE_SERVER_NAME=前端地址 synapse generate</code> 命令生成配置文件,之后检查在 <code>./synapse/data</code> 路径下是否有叫 <code>homeserver.yaml</code> 的配置文件,编辑配置文件 <code>nano ./synapse/data/homeserver.yaml</code></li></ul><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 重点改以下配置</span></span><br><span class="line"><span class="attr">server_name:</span> <span class="string">&quot;matrix.org&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="attr">public_baseurl:</span> <span class="string">https://synapse.matrix.org/</span></span><br><span class="line"></span><br><span class="line"><span class="attr">serve_server_wellknown:</span> <span class="literal">true</span></span><br><span class="line"></span><br><span class="line"><span class="attr">database:</span></span><br><span class="line"> <span class="attr">name:</span> <span class="string">psycopg2</span></span><br><span class="line"> <span class="attr">txn_limit:</span> <span class="number">10000</span></span><br><span class="line"> <span class="attr">args:</span></span><br><span class="line"> <span class="attr">user:</span> <span class="string">synapse</span></span><br><span class="line"> <span class="attr">password:</span> <span class="string">docker</span> <span class="string">配置写的随便什么密码</span></span><br><span class="line"> <span class="attr">database:</span> <span class="string">synapse</span></span><br><span class="line"> <span class="attr">host:</span> <span class="string">db</span></span><br><span class="line"> <span class="attr">port:</span> <span class="number">5432</span></span><br><span class="line"> <span class="attr">cp_min:</span> <span class="number">5</span></span><br><span class="line"> <span class="attr">cp_max:</span> <span class="number">10</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#database:</span></span><br><span class="line"><span class="comment"># name: sqlite3</span></span><br><span class="line"><span class="comment"># args:</span></span><br><span class="line"><span class="comment"># database: /data/homeserver.db</span></span><br><span class="line"><span class="comment">#↑注释掉使用 sqlite3 的配置</span></span><br><span class="line"></span><br><span class="line"><span class="attr">redis:</span></span><br><span class="line"> <span class="comment"># Uncomment the below to enable Redis support.</span></span><br><span class="line"> <span class="comment">#</span></span><br><span class="line"> <span class="attr">enabled:</span> <span class="literal">true</span></span><br><span class="line"></span><br><span class="line"> <span class="comment"># Optional host and port to use to connect to redis. Defaults to</span></span><br><span class="line"> <span class="comment"># localhost and 6379</span></span><br><span class="line"> <span class="comment">#</span></span><br><span class="line"> <span class="attr">host:</span> <span class="string">redis</span></span><br><span class="line"> <span class="attr">port:</span> <span class="number">6379</span></span><br></pre></td></tr></table></figure><ul><li>之后再启动服务,<code>docker-compose start</code></li><li>编辑 <code>matrix.org</code> 的 <code>nginx</code> 配置文件加入以下配置</li></ul><figure class="highlight nginx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"> <span class="section">location</span> /.well-known/matrix/client &#123;</span><br><span class="line"> <span class="attribute">return</span> <span class="number">200</span> <span class="string">&#x27;&#123;&quot;m.homeserver&quot;: &#123;&quot;base_url&quot;: &quot;synapse.matrix.org&quot;&#125;&#125;&#x27;</span>;</span><br><span class="line"> <span class="attribute">default_type</span> application/json;</span><br><span class="line"> <span class="attribute">add_header</span> Access-Control-Allow-Origin *;</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="section">location</span> /.well-known/matrix/server &#123;</span><br><span class="line"> <span class="attribute">return</span> <span class="number">200</span> <span class="string">&#x27;&#123;&quot;m.server&quot;: &quot;synapse.matrix.org:443&quot;&#125;&#x27;</span>;</span><br><span class="line"> <span class="attribute">default_type</span> application/json;</span><br><span class="line"> <span class="attribute">add_header</span> Access-Control-Allow-Origin *;</span><br><span class="line"> &#125;</span><br><span class="line"><span class="comment">#注意替换自己的前端后端地址</span></span><br></pre></td></tr></table></figure><ul><li>新建 <code>synapse.matrix.org</code> 的 <code>dns</code> ,指向服务器地址,再 <code>certbot certonly --nginx -d synapse.matrix.org</code> 申请证书</li><li>新建一个 <code>synapse.matrix.org</code> 的配置文件</li></ul><figure class="highlight nginx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">server</span> &#123;</span><br><span class="line"> <span class="attribute">listen</span> <span class="number">443</span> ssl http2;</span><br><span class="line"> <span class="attribute">listen</span> [::]:<span class="number">443</span> ssl http2;</span><br><span class="line"></span><br><span class="line"> <span class="attribute">server_name</span> synapse.matrix.org;</span><br><span class="line"></span><br><span class="line"> <span class="attribute">ssl_certificate</span> /etc/letsencrypt/live/synapse.matrix.org/fullchain.pem;</span><br><span class="line"> <span class="attribute">ssl_certificate_key</span> /etc/letsencrypt/live/synapse.matrix.org/privkey.pem;</span><br><span class="line"></span><br><span class="line"> <span class="comment"># Various TLS hardening settings</span></span><br><span class="line"> <span class="comment"># https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html</span></span><br><span class="line"> <span class="attribute">ssl_protocols</span> TLSv1.<span class="number">2</span> TLSv1.<span class="number">3</span>;</span><br><span class="line"> <span class="attribute">ssl_prefer_server_ciphers</span> <span class="literal">on</span>;</span><br><span class="line"> <span class="attribute">ssl_ciphers</span> ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384;</span><br><span class="line"> <span class="attribute">ssl_session_timeout</span> <span class="number">10m</span>;</span><br><span class="line"> <span class="attribute">ssl_session_cache</span> shared:SSL:<span class="number">10m</span>;</span><br><span class="line"> <span class="attribute">ssl_session_tickets</span> <span class="literal">on</span>;</span><br><span class="line"> <span class="attribute">ssl_stapling</span> <span class="literal">on</span>;</span><br><span class="line"> <span class="attribute">ssl_stapling_verify</span> <span class="literal">on</span>;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"> <span class="section">location</span> <span class="regexp">~ ^(/_matrix|/_synapse/client)</span> &#123;</span><br><span class="line"> <span class="comment"># note: do not add a path (even a single /) after the port in `proxy_pass`,</span></span><br><span class="line"> <span class="comment"># otherwise nginx will canonicalise the URI and cause signature verification</span></span><br><span class="line"> <span class="comment"># errors.</span></span><br><span class="line"> <span class="attribute">proxy_pass</span> http://127.0.0.1:8001;</span><br><span class="line"> <span class="attribute">proxy_set_header</span> X-Forwarded-For <span class="variable">$remote_addr</span>;</span><br><span class="line"> <span class="attribute">proxy_set_header</span> X-Forwarded-Proto <span class="variable">$scheme</span>;</span><br><span class="line"> <span class="attribute">proxy_set_header</span> Host <span class="variable">$host</span>;</span><br><span class="line"></span><br><span class="line"> <span class="comment"># Nginx by default only allows file uploads up to 1M in size</span></span><br><span class="line"> <span class="comment"># Increase client_max_body_size to match max_upload_size defined in homeserver.yaml</span></span><br><span class="line"> <span class="attribute">client_max_body_size</span> <span class="number">500M</span>;</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><ul><li>重载 <code>nginx</code> 配置文件,<code>nginx -s reload</code></li><li>之后去<a href="https://federationtester.matrix.org/">检查服务</a>(需科学)输入自己的前端地址 <code>matrix.org</code> 检查是否正常</li><li>用 <code>docker-compose exec synapse /bin/bash</code> 进入 <code>synapse</code> 容器</li></ul><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">cd data</span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash">注册新用户</span></span><br><span class="line">register_new_matrix_user -c homeserver.yaml http://localhost:8008 </span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash">注册完后用 <span class="built_in">exit</span> 退出容器</span></span><br><span class="line">exit</span><br></pre></td></tr></table></figure><ul><li>完成后用任意一个客户端登陆即可使用,注意登陆用的地址是后端地址 <code>synapse.matrix.org</code></li></ul>]]></content:encoded>
<category domain="https://blog.southfox.me/categories/%E6%8A%80%E6%9C%AF/">技术</category>
<category domain="https://blog.southfox.me/tags/%E6%8A%80%E6%9C%AF/">技术</category>
<comments>https://blog.southfox.me/2022/04/%E6%90%AD%E5%BB%BAMatrix%E5%8D%B3%E6%97%B6%E9%80%9A%E4%BF%A1%E6%9C%8D%E5%8A%A1/#disqus_thread</comments>
</item>
<item>
<title>EFK:日志 All in one……</title>
<link>https://blog.southfox.me/2022/04/EFK-%E6%97%A5%E5%BF%97-All-in-one/</link>
<guid>https://blog.southfox.me/2022/04/EFK-%E6%97%A5%E5%BF%97-All-in-one/</guid>
<pubDate>Mon, 04 Apr 2022 17:04:30 GMT</pubDate>
<description>&lt;p&gt;突然发现自己搭的应用似乎上了两位数了。&lt;/p&gt;</description>
<content:encoded><![CDATA[<p>突然发现自己搭的应用似乎上了两位数了。</p><span id="more"></span><p>其中也不乏一些日志大户,每次排错时都要自己进去用日志命令脑死 <code>PgUp, PgDn</code> 一页一页翻找吗?</p><p>刚好最近看的书里提出了一种日志管理实现:<code>ELK</code>,即 <code>Elasticsearch, Logstash, Kibana</code> 三种开源应用的简称,其中:</p><p><code>Elasticsearch</code>:负责给日志数据产生索引,方便检索。</p><p><code>Logstash</code>:接收并处理日志,方便其他应用使用。</p><p><code>Kibana</code>:一个展示前端,有酷炫的一众图表模板用来可视化数据。</p><p>似乎名头一直都在很多年了,使用起来似乎比较重量级,不知道有没有其他更轻量的实现……不过我也找不到其他实现就先这么用吧……</p><h2 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h2><p>因为搭建的应用以 <code>Docker</code> 居多,其中默认支持的日志方式有 <code>Fluentd</code>,所以就用这个代替 <code>Logstash</code> 了,所以是 <code>EFK</code> 方案。</p><p><code>Fluentd</code> 采用包安装的方式安装,毕竟要用它处理宿主机上的一些日志,就不考虑塞到 <code>Docker</code> 里折腾自己了。</p><h3 id="前期准备"><a href="#前期准备" class="headerlink" title="前期准备"></a>前期准备</h3><p>参见<a href="https://docs.fluentd.org/installation/before-install">官网文档</a></p><h4 id="安装-chrony"><a href="#安装-chrony" class="headerlink" title="安装 chrony"></a>安装 chrony</h4><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">apt-get install chrony</span><br></pre></td></tr></table></figure><p>此步骤是为了日志消息能有更准确的时间戳的样子?</p><h4 id="调高文件描述符"><a href="#调高文件描述符" class="headerlink" title="调高文件描述符"></a>调高文件描述符</h4><p>执行</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ulimit -n</span><br></pre></td></tr></table></figure><p>命令,要是显示 <code>1024</code> 的话,那么就得调高一点,防止文件描述符用完报错,</p><p>编辑 <code>/etc/security/limits.conf</code> 文件,在最后面加上:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">root soft nofile 65536</span><br><span class="line">root hard nofile 65536</span><br><span class="line">* soft nofile 65536</span><br><span class="line">* hard nofile 65536</span><br></pre></td></tr></table></figure><p>之后重启,再次执行</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ulimit -n</span><br></pre></td></tr></table></figure><p>命令,显示 <code>65536</code> 即可成功。</p><h4 id="其他"><a href="#其他" class="headerlink" title="其他"></a>其他</h4><p>其他的网络调优懒得搞了……问就是摸了!</p><h3 id="安装-Fluentd"><a href="#安装-Fluentd" class="headerlink" title="安装 Fluentd"></a>安装 Fluentd</h3><p>用的是 <code>Ububtu 20.04</code> ,参照<a href="https://docs.fluentd.org/installation/install-by-deb">官方文档</a>,执行</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">curl -fsSL https://toolbelt.treasuredata.com/sh/install-ubuntu-focal-td-agent4.sh | sh</span><br></pre></td></tr></table></figure><p>而且里面的版本描述是用大版本号的英文描述的,还得我翻<a href="https://zh.wikipedia.org/zh/Ubuntu">维基</a>查,好好用阿拉伯数字不好嘛……</p><h3 id="安装-EK"><a href="#安装-EK" class="headerlink" title="安装 EK"></a>安装 EK</h3><p>这里就用 <code>Docker</code> 省点力了……</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">version:</span> <span class="string">&#x27;3&#x27;</span></span><br><span class="line"><span class="attr">services:</span></span><br><span class="line"> <span class="attr">elasticsearch:</span></span><br><span class="line"> <span class="attr">image:</span> <span class="string">elasticsearch:tag</span></span><br><span class="line"> <span class="attr">restart:</span> <span class="string">always</span></span><br><span class="line"> <span class="attr">ports:</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">&quot;127.0.0.1:9200:9200&quot;</span></span><br><span class="line"> <span class="attr">environment:</span></span><br><span class="line"> <span class="attr">ES_JAVA_OPTS:</span> <span class="string">&quot;-Xmx256m -Xms256m&quot;</span></span><br><span class="line"> <span class="attr">ELASTIC_PASSWORD:</span> <span class="string">&quot;you_password&quot;</span></span><br><span class="line"> <span class="attr">http.cors.enabled:</span> <span class="string">&quot;true&quot;</span></span><br><span class="line"> <span class="attr">http.cors.allow-origin:</span> <span class="string">&quot;*&quot;</span></span><br><span class="line"> <span class="attr">xpack.security.enabled:</span> <span class="string">&quot;true&quot;</span></span><br><span class="line"> <span class="attr">discovery.type:</span> <span class="string">&quot;single-node&quot;</span></span><br><span class="line"> <span class="attr">xpack.security.authc.api_key.enabled:</span> <span class="string">&quot;true&quot;</span></span><br><span class="line"></span><br><span class="line"> <span class="attr">kibana:</span></span><br><span class="line"> <span class="attr">image:</span> <span class="string">kibana:tag</span></span><br><span class="line"> <span class="attr">restart:</span> <span class="string">always</span></span><br><span class="line"> <span class="attr">links:</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">&quot;elasticsearch&quot;</span></span><br><span class="line"> <span class="attr">ports:</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">&quot;127.0.0.1:5601:5601&quot;</span></span><br><span class="line"> <span class="attr">environment:</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">ELASTICSEARCH_USERNAME=elastic</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">ELASTICSEARCH_PASSWORD=&quot;you_password&quot;</span></span><br></pre></td></tr></table></figure><p> 其中 <code>tag</code> 应该去 <a href="https://hub.docker.com/_/elasticsearch"><code>Docker Hub</code> 页面</a>寻找,因为没有默认标签的样子只能手动指定版本了……而且注意要选择修了高危漏洞的版本。</p><p>之后 <code>up</code> 起来待用。</p><p><strong>注意</strong>这里没做数据持久化处理,有兴趣的可以自行找找要挂载哪些路径……)</p><h2 id="配置"><a href="#配置" class="headerlink" title="配置"></a>配置</h2><h3 id="Fluentd"><a href="#Fluentd" class="headerlink" title="Fluentd"></a>Fluentd</h3><p>配置文件路径是 <code>/etc/td-agent/td-agent.conf</code> </p><p>其中分为 <code>Input</code> 端,用 <code>&lt;sourec&gt;</code> 表示,<code>Output</code> 端,用 <code>&lt;match&gt;</code> 处理。</p><p>首先增加以下:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line">&lt;source&gt;</span><br><span class="line"> @type forward</span><br><span class="line"> port 24224</span><br><span class="line"> bind 127.0.0.1</span><br><span class="line">&lt;/source&gt;</span><br><span class="line"></span><br><span class="line">&lt;match *.**&gt;</span><br><span class="line"> @type copy</span><br><span class="line"></span><br><span class="line"> &lt;store&gt;</span><br><span class="line"> @type elasticsearch</span><br><span class="line"> host 127.0.0.1</span><br><span class="line"> port 9200</span><br><span class="line"> user elastic</span><br><span class="line"> password you_password</span><br><span class="line"> logstash_format true</span><br><span class="line"> logstash_prefix fluentd</span><br><span class="line"> logstash_dateformat %Y%m%d</span><br><span class="line"> include_tag_key true</span><br><span class="line"> type_name access_log</span><br><span class="line"> tag_key @log_name</span><br><span class="line"> flush_interval 1s</span><br><span class="line"> &lt;/store&gt;</span><br><span class="line"></span><br><span class="line"> &lt;store&gt;</span><br><span class="line"> @type stdout</span><br><span class="line"> &lt;/store&gt;</span><br><span class="line">&lt;/match&gt;</span><br></pre></td></tr></table></figure><p>并且 <code>systemctl restart td-agent</code> 重启应用,开放<code>24224</code> 端口让 <code>Docker</code> 能够进行联协,并将相应数据通过 <code>9200</code> 端口汇入到 <code>Elasticsearch</code> 进行处理。</p><h3 id="Docker"><a href="#Docker" class="headerlink" title="Docker"></a>Docker</h3><p>管理每个 <code>docker-compose.yml</code> 文件,在每个服务后面加上相应的 <code>logging</code> 块:</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">services:</span></span><br><span class="line"> <span class="attr">xxx:</span></span><br><span class="line"> <span class="string">......</span></span><br><span class="line"> <span class="string">......</span></span><br><span class="line"> <span class="attr">logging:</span></span><br><span class="line"> <span class="attr">driver:</span> <span class="string">fluentd</span></span><br><span class="line"> </span><br><span class="line"> <span class="attr">yyy:</span></span><br><span class="line"> <span class="string">......</span></span><br><span class="line"> <span class="string">......</span></span><br><span class="line"> <span class="attr">logging:</span></span><br><span class="line"> <span class="attr">driver:</span> <span class="string">fluentd</span></span><br></pre></td></tr></table></figure><p>(是的,感觉这样确实有点蠢,不过没找到其他更好实现而且只要做一次就先忍了……)</p><p>之后 <code>down</code> 再 <code>up</code> 重建容器即可。</p><h3 id="Kibana"><a href="#Kibana" class="headerlink" title="Kibana"></a>Kibana</h3><p>没出错的话现在日志应该源源不断汇入到 <code>Elasticsearch</code> 并在处理了,现在该浏览成果了。</p><p>老调重弹之申请域名、指向域名、申请证书、反代 <code>5601</code> 端口,完成后访问对应域名应该就能进到管理面板了。</p><p>展开左边的菜单栏 <code>Management~Stack Management -&gt; Kibana~Index patterns -&gt; Create index patterns </code> 应该能看到有类似 <code>fluentd-YYMMDD</code> 形式的数据了,新建一个名叫 <code>fluentd-*</code> 的索引将数据囊括进来,就搞定了,之后可以去 <code>Analytics~Discover</code> 查看数据了……</p><p>到此,管理 <code>Docker</code> 产生的日志就这样搞定了……</p><h2 id="额外"><a href="#额外" class="headerlink" title="额外"></a>额外</h2><p>当然还没结束,毕竟还要更多!</p><h3 id="Nginx"><a href="#Nginx" class="headerlink" title="Nginx"></a>Nginx</h3><p><code>Fluentd</code> 直接安装就是为了更方便处理相应日志的,但是针对 <code>nginx</code> 来说,因为 <code>Fluentd</code> 使用的用户 <code>td-agent</code> 没有相应访问 <code>nginx</code> 日志的权限,那么首先要用</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">usermod -aG adm td-agent</span><br></pre></td></tr></table></figure><p>命令放行对应目录,<a href="https://docs.fluentd.org/parser#how-to-use">参见</a>。</p><p>之后在 <code>/etc/td-agent/td-agent.conf</code> 配置文件中新增以下配置:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">&lt;source&gt;</span><br><span class="line"> @type tail</span><br><span class="line"> path /var/log/nginx/*access.log,/var/log/nginx/*access.log.1</span><br><span class="line"> pos_file /var/log/td-agent/httpd-access.log.pos</span><br><span class="line"> tag nginx.access</span><br><span class="line"> &lt;parse&gt;</span><br><span class="line"> @type nginx</span><br><span class="line"> &lt;/parse&gt;</span><br><span class="line">&lt;/source&gt;</span><br><span class="line"></span><br><span class="line">&lt;source&gt;</span><br><span class="line"> @type tail</span><br><span class="line"> path /var/log/nginx/*error.log,/var/log/nginx/*erroe.log.1</span><br><span class="line"> pos_file /var/log/td-agent/httpd-error.log.pos</span><br><span class="line"> tag nginx.error</span><br><span class="line"> &lt;parse&gt;</span><br><span class="line"> @type nginx</span><br><span class="line"> &lt;/parse&gt;</span><br><span class="line">&lt;/source&gt;</span><br></pre></td></tr></table></figure><p>然后 <code>systemctl restart td-agent</code> 重启应用。</p><p>其中一个小问题就是 <code>error</code> 日志会因为不能格式化而导致不能正确处理,当然只限 <code>error</code> 日志,所以就……眼不见为净了……反正这也算单独一个分类了……吧。</p><h3 id="网络传输"><a href="#网络传输" class="headerlink" title="网络传输"></a>网络传输</h3><p>既然 <code>All in one</code>,自然要处理好其他主机的服务了, <code>Fluentd</code> 也自带一个 <code>http</code> 方式进行传输。</p><h4 id="主机"><a href="#主机" class="headerlink" title="主机"></a>主机</h4><p>在 <code>/etc/td-agent/td-agent.conf</code> 配置文件中新增以下配置:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">&lt;source&gt;</span><br><span class="line"> @type http</span><br><span class="line"> port 9880</span><br><span class="line"> bind 127.0.0.1</span><br><span class="line"> body_size_limit 32m</span><br><span class="line"> keepalive_timeout 10s</span><br><span class="line">&lt;/source&gt;</span><br></pre></td></tr></table></figure><p>然后 <code>systemctl restart td-agent</code> 重启应用,再老调重弹之申请域名、指向域名、申请证书、反代 <code>9800</code> 端口。</p><h4 id="客机"><a href="#客机" class="headerlink" title="客机"></a>客机</h4><p>在 <code>/etc/td-agent/td-agent.conf</code> 配置文件中新增以下配置:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">&lt;match **&gt;</span><br><span class="line"> @type http</span><br><span class="line"></span><br><span class="line"> endpoint https://申请的域名:443/api</span><br><span class="line"> open_timeout 3</span><br><span class="line"></span><br><span class="line"> &lt;format&gt;</span><br><span class="line"> @type json</span><br><span class="line"> &lt;/format&gt;</span><br><span class="line"> json_array true</span><br><span class="line"> &lt;buffer&gt;</span><br><span class="line"> flush_interval 10s</span><br><span class="line"> &lt;/buffer&gt;</span><br><span class="line">&lt;/match&gt;</span><br></pre></td></tr></table></figure><p>然后 <code>systemctl restart td-agent</code> 重启应用,</p><p>之后观察 <code>Kibana</code> 面板,发现有 <code>@logname</code> 为 <code>api</code> 的数据就算成功……这个 <code>logname</code> 发现不知道怎么改……算了,就当作区分不同机子了吧……</p><h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p>这么处理下来,就应该能愉快的探索自己产生的日志了,能够直接指定时间段和按属性过滤条目已经暴杀直接翻找日志文件的方式了……</p><p>感觉能摸索的地方还有挺多的呢,不用各种追踪脚本仅凭日志文件也能发现很多东西呢……</p><p>不过难受的点就是,<code>EFK</code> 名头那么大,但是相关文档真的很少(就算用英文搜索)……感觉自己在用一个过气项目的样子,不知道是不是我不得要领……</p><p>最后附张图,用面板五分钟就搭出来的看板,感觉还能再挖掘点东西呢。</p><p><img src="https://media.southfox.me/ipfs/bafkreicf4fknbhjyqw5dgh5vgg5pfl6fx2bwiiw745pun7ap7zf3tzdqdy" alt="看板"></p>]]></content:encoded>
<category domain="https://blog.southfox.me/categories/%E6%8A%80%E6%9C%AF/">技术</category>
<category domain="https://blog.southfox.me/tags/%E6%8A%80%E6%9C%AF/">技术</category>
<comments>https://blog.southfox.me/2022/04/EFK-%E6%97%A5%E5%BF%97-All-in-one/#disqus_thread</comments>
</item>
<item>
<title>二二年三月梦记</title>
<link>https://blog.southfox.me/2022/03/%E4%BA%8C%E4%BA%8C%E5%B9%B4%E4%B8%89%E6%9C%88%E6%A2%A6%E8%AE%B0/</link>
<guid>https://blog.southfox.me/2022/03/%E4%BA%8C%E4%BA%8C%E5%B9%B4%E4%B8%89%E6%9C%88%E6%A2%A6%E8%AE%B0/</guid>
<pubDate>Tue, 08 Mar 2022 15:03:28 GMT</pubDate>
<description>&lt;p&gt;一声叹息。&lt;/p&gt;</description>
<content:encoded><![CDATA[<p>一声叹息。</p><span id="more"></span><h2 id="3-8"><a href="#3-8" class="headerlink" title="3.8"></a>3.8</h2><p>中 普</p><h3 id="起"><a href="#起" class="headerlink" title="起"></a>起</h3><p>又是常见的校园怪谈啦,一些学生会莫名其妙消失不见啦。</p><p>我就是在这种情况下打算返校的。</p><h3 id="公园"><a href="#公园" class="headerlink" title="公园"></a>公园</h3><p>逛公园,似乎这只是一个稀松平常的景点。我路过一个冰淇淋摊贩,他问我你要不要来点?我接过,然后就看着冰淇淋……仍由它融化。**</p><h3 id="返校"><a href="#返校" class="headerlink" title="返校"></a>返校</h3><p>雨,好大的雨!</p><p>我顶着雨伞也难免被吹得几乎飞起来!艰难的到了教学楼下,一层……二层……三层……楼梯是外露的,所以不免也要承受风雨,四层以上的楼梯甚至还没有护栏!我已经被吹得摇摇晃晃的了,想着之前也有些喜欢玩闹的学生坠楼的传言,我抛弃雨伞,直接抱紧扶手,像毛毛虫一样爬了上去……</p><h4 id="校园间"><a href="#校园间" class="headerlink" title="校园间"></a>校园间</h4><p><strong>「记忆混乱——」</strong></p><p>一些大学老师和高中混在了一起,以及一些稀奇古怪的上课内容……哪怕才过去二十分钟,就已经模糊不堪……似乎潜意识是真不想我回忆这块内容吧……</p><h4 id="但有一幕"><a href="#但有一幕" class="headerlink" title="但有一幕"></a>但有一幕</h4><p>我在楼道直接跑动,为了追逐一个朋友,我追到电梯房,他已经抢先一步上去了……</p><blockquote><p>这里的感觉不是他躲着不想见我,而是更像损友之间的小玩笑,但他现实中不是这样的人……我是把他跟谁整合到一起了?</p></blockquote><h3 id="漫漫回家路"><a href="#漫漫回家路" class="headerlink" title="漫漫回家路"></a>漫漫回家路</h3><p>校园状况越发差劲……学校决定让我们回去。</p><p>我站到回家路上的一条街道……已经眼前发黑,腿脚难行……</p><p>压抑……</p><p><strong>「记忆丢失」</strong></p><h3 id="到家"><a href="#到家" class="headerlink" title="到家"></a>到家</h3><p>我从后门回家,发现我爸又在搞装修,把门换了新的。我的房间门下方换成玻璃制的了,能够一眼看到我的床……</p><blockquote><p>父母的控制欲?但是梦里的我并没有太过惊讶,所以这层含义算是最浅显也最不主要的部分了。</p></blockquote><p>我前往阳台,发现也堆着很多门……</p><blockquote><p>下方没玻璃。</p></blockquote><p>我通过窗户望向我哥的房间,发现我爸正睡在那里。</p><blockquote><p>我竟然没感到奇怪。</p></blockquote><p><strong>「记忆丢失」</strong></p><p>我似乎立于天空中,中间写着几行字。</p><p>橙色</p><p>蓝色</p><p>绿色</p><p>似乎都是些颜色名字,都是些什么?</p><p>……</p><p>我打算进我爸房间了,告诉他我回来了。</p><p>推开门,我就发现不对了!那个怪谈,那个让人消失的怪谈!它就在房间里!</p><p>它在四面八方涌上来!</p><p><strong>“够了!”</strong></p><p>“我已经不想待在这压抑的梦了!”,我说道。</p><p>“你究竟是什么东西!”,我将这股情绪狂潮指向房间中不可见的存在,势要揪出来它的原型。</p><p>…………</p><p>深海……鲜艳的热带鱼群……</p><p>……奇怪的绿色类鱼生物……带有双肢的……冲向海面……</p><p>…………</p><p>所以,橙色是,自负的意思?</p><p>我喃喃自语……</p><blockquote><p>梦里半清醒的我向梦直接发问也没能获得个完整清晰的解析。</p><p>这次的梦,真的太奇怪了……</p></blockquote><h3 id="中场休息"><a href="#中场休息" class="headerlink" title="中场休息"></a>中场休息</h3><p>我清醒了……拿起手机一看,才十四点半。</p><p>再继续睡吧……接下来的梦就回归正常了,还大多跟 MOBA 游戏有关大概跟我在睡前刷的B站视频有关吧。</p><h3 id="友善评论"><a href="#友善评论" class="headerlink" title="友善评论"></a>友善评论</h3><p>我来到一个游戏展会上,一个看板是写着对于游戏的祝福,上面也充斥着“祝福”。</p><p>「蒸蒸日上」「ez 策划!」……</p><p>都是些没吐脏字骂人的话语……</p><h3 id="称号"><a href="#称号" class="headerlink" title="称号"></a>称号</h3><p>一款猪场或者企鹅出品的手游,似乎出了个「头号玩家」的礼包,仅需小几万就能拥有个自定义称号。</p><p>于是很多土豪蹲点购买……但起得称号哭笑不得,政治、人物啥的敏感称号使劲往上取。</p><h3 id="改版"><a href="#改版" class="headerlink" title="改版"></a>改版</h3><p>似乎是猪场的扒鸡,似乎我又回坑玩了。</p><p>我常玩的英雄被改版了,被动成了个死后成为灵魂状态读秒然后还可以放技能读秒完还能原地复活的样子?这改版让这英雄从躲在后方猥琐放技能变成往前莽的类型了……</p><p>对面发育非常好,我方翻盘点全压在我身上,于是变成我死了都要输出对面,对方也守我尸蹲我复活点然后再把我打死的拉扯局面。</p><p>来来回回几次后,我感觉,够了!我已经没有耐心了,我要醒了,就算你们直接输了。</p><p>于是我醒了,看了眼时间,十四点五十分……</p><h2 id="3-9"><a href="#3-9" class="headerlink" title="3.9"></a>3.9</h2><p>中 普</p><h3 id="舍友"><a href="#舍友" class="headerlink" title="舍友"></a>舍友</h3><p>某个女主播住在我们宿舍……</p><p>……</p><p>我似乎到网上申请了一个去分布网络的 ID </p><h2 id="3-16"><a href="#3-16" class="headerlink" title="3.16"></a>3.16</h2><p>中 普</p><h3 id="屏蔽我!"><a href="#屏蔽我!" class="headerlink" title="屏蔽我!"></a>屏蔽我!</h3><p>一个社交网站的页面,似乎是我发的……上面写着,某个站的用户看不惯我就屏蔽我吧。</p><h2 id="3-22"><a href="#3-22" class="headerlink" title="3.22"></a>3.22</h2><p>中 普</p><h3 id="地球炸了"><a href="#地球炸了" class="headerlink" title="地球炸了"></a>地球炸了</h3><p>苍茫宇宙中,宇宙突然开裂,崩解成一大堆碎片。其中一个大的球形碎片在其中穿梭……</p><p>“是月球啊,月球也可以算是地球的碎片了吧,要是月球能持续吸引周围的碎片,那么地球或许会重新回来吧……”</p><h3 id="暴雨"><a href="#暴雨" class="headerlink" title="暴雨"></a>暴雨</h3><p>我的床铺不知道为什么放在了阳台上,而外面已经阴沉起来了,天空压抑……</p><p>我突然惊觉起来……疯了似的把被子踢到前面,想为自己遮点雨……但是雨夹着雨还是让我浑身湿落。</p><p>…………</p><p>(中间似乎假醒了一次?)</p><h3 id="再起"><a href="#再起" class="headerlink" title="再起"></a>再起</h3><p>我听到了舍友敲打的键盘声,醒了过来。我下了床,走到阳台,发现我的床已经湿透了,插座放在拐角处……上面的屏幕暴亮着,提醒着我已经工作不能……</p><p>我从阳台望出去,已是深夜,心思不平,想着之后该如何……我转身回到宿舍内,发现舍友还在交谈着……</p><p>我突然意识到,是梦!</p><p>我开始愤愤不平起来,马上冲到一个舍友旁,强硬夺下他的眼睛,喊道——“变!”</p><p>他随即头部变成了一只柴犬头……</p><blockquote><p>为什么是柴犬?额,但更关键的是他似乎不是现实舍友,似乎是某个高中同学……</p></blockquote><p>之后我想出去逛一逛,但发现夜色已经哪里都是,无法再出现什么具体的东西了,大概是之前的那个地球炸掉的场景把脑子的渲染配额用完了吧……</p><p>那只好起来了,打开手机,发现天气预报发来暴雨预警……外面已有阵阵雷声……</p>]]></content:encoded>
<category domain="https://blog.southfox.me/categories/%E6%A2%A6%E8%AE%B0/">梦记</category>
<category domain="https://blog.southfox.me/tags/%E6%A2%A6%E8%AE%B0/">梦记</category>
<comments>https://blog.southfox.me/2022/03/%E4%BA%8C%E4%BA%8C%E5%B9%B4%E4%B8%89%E6%9C%88%E6%A2%A6%E8%AE%B0/#disqus_thread</comments>
</item>
<item>
<title>Github Actions 浅尝辄止</title>
<link>https://blog.southfox.me/2022/03/Github-Actions-%E6%B5%85%E5%B0%9D%E8%BE%84%E6%AD%A2/</link>
<guid>https://blog.southfox.me/2022/03/Github-Actions-%E6%B5%85%E5%B0%9D%E8%BE%84%E6%AD%A2/</guid>
<pubDate>Mon, 07 Mar 2022 16:32:14 GMT</pubDate>
<description>&lt;p&gt;免费送!免费送!微软电脑免费送啦!&lt;/p&gt;</description>
<content:encoded><![CDATA[<p>免费送!免费送!微软电脑免费送啦!</p><span id="more"></span><p>自从 <code>GitHub</code> 被微软收购以后确实是有钱了啊,<code>GitHub Actions</code> 公开仓库竟然可以免费用(私有仓库也有三千分钟时间)。</p><p>什么?不知道 <code>GitHub Actions</code> 是什么?</p><p>简单来说就是提前写好对应的配置文件,那么 <code>GitHub</code> 就会在满足条件时分配电脑执行对应的配置文件,配置文件可以包含命令或者引用其他人写好的配置文件……所以这如同有一台真实的服务器一般强大。</p><p>本来呢,这种服务是为了方便一众开源应用测试和编译的,但是被一众羊毛党薅出花来了……什么自动签到啦、生成订阅源啦、推送消息啦等等等等,这些「奇技淫巧」可以在各家推荐专栏找到,有兴趣可以自己去找一下。</p><p>还是说说我拿 <code>GitHub Actions</code> 来干什么吧。</p><h2 id="Hexo-自动部署"><a href="#Hexo-自动部署" class="headerlink" title="Hexo 自动部署"></a>Hexo 自动部署</h2><p>如果经管着一个静态博客那么这功能是刚需了吧,毕竟如果想在移动设备或者不方便安装环境的公用电脑上写作的话,那么让 <code>Actions</code> 进行生成静态页面和部署是一个优秀的选择。</p><h3 id="生成-Personal-access-tokens"><a href="#生成-Personal-access-tokens" class="headerlink" title="生成 Personal access tokens"></a>生成 Personal access tokens</h3><p>因为分配的机器是一个干净的环境,并没有操作对应 <code>GitHub</code> 仓库的能力,为了做到登陆,首先需要生成一个 <code>access tokens</code> 。(当然也可以用私钥认证,但是感觉麻烦就没用这方式……)</p><p>首先到 <a href="https://github.com/settings/tokens">GitHub 配置页</a> 点击 <code>Generate new token</code> 按钮,输入密码认证后跳转到对应页面。</p><p><code>Note</code> 填写一个便于理解的名称,我这边是用来自动部署 <code>Hexo</code> 博客就写 <code>HEXO_DEPLOY </code> 。</p><p>然后选择过期日期(<code>Expiration</code>),如果不嫌麻烦并确信自己不会忘记更换,那么可以设置一年两年的过期时限,否则懒人就选永不过期吧( <code>No expiration</code>)吧……</p><p>然后在权限范围(<code>Select scopes</code>)栏里勾选 <code>repo</code> 框(如果能明确对应权限是干嘛的也可以只勾选需要的权限)。</p><p>然后点击生成按钮(<code>Generate token</code>)生成一个新的 <code>access tokens</code> ,这个页面只显示一次,所以不要关闭窗口!</p><h3 id="设置-Actions-secrets"><a href="#设置-Actions-secrets" class="headerlink" title="设置 Actions secrets"></a>设置 Actions secrets</h3><p>除非你是私有仓库,那么运行 <code>actions</code> 的配置文件和所有输出对所有人都是可见的,为了安全,要自己设定一个<code>Actions secrets</code> 隐藏相关的 <code>token</code> 。</p><p>新开一个页面,到存储 <code>Hexo</code> 博客文件的仓库, <code>Settins -&gt; Secrets -&gt; Actions -&gt; 点击 New repository secret 按钮</code> ,然后新页面 <code>Name</code> 填写便于理解的名称 ,我这边是用来自动部署 <code>Hexo</code> 博客就写 <code>HEXO_DEPLOY </code> 。值(<code>Value</code>)里填写上一步 <code>Generate token</code> 生成的 <code>token</code> ,然后点击 <code> Add secret</code> 保存 <code>secrets</code> 。</p><h3 id="编写配置文件"><a href="#编写配置文件" class="headerlink" title="编写配置文件"></a>编写配置文件</h3><p>做好前期工作后就到激动人心的写配置时间喽。</p><p>首先在 <code>Git</code> 仓库根目录下新建一个 <code>.github</code> 文件夹,然后再在里面新建一个 <code>workflows</code> 文件夹,再在里面新建一个 <code>xxx.yml</code> 文件,我的形式是 <code>仓库/.github/workflows/deploy.yml</code> 。</p><p>之后就该往 <code>.yml</code> 文件写配置了,<code>yml</code> 格式是一个严格缩进格式,所以对自己好点,用 <code>VS Code</code> 之类的编辑器来写……</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">name:</span> <span class="string">Hexo</span> <span class="string">Deploy</span></span><br><span class="line"></span><br><span class="line"><span class="attr">on:</span></span><br><span class="line"> <span class="attr">push:</span></span><br><span class="line"> <span class="attr">branches:</span> [ <span class="string">hexo</span> ]</span><br><span class="line"></span><br><span class="line"><span class="attr">jobs:</span></span><br><span class="line"> <span class="attr">build:</span></span><br><span class="line"></span><br><span class="line"> <span class="attr">runs-on:</span> <span class="string">ubuntu-latest</span></span><br><span class="line"> <span class="attr">strategy:</span></span><br><span class="line"> <span class="attr">fail-fast:</span> <span class="literal">false</span></span><br><span class="line"> </span><br></pre></td></tr></table></figure><p><code>name</code> 那一栏填便于理解的名字。</p><p><code>on</code> 选项是为监听哪个分支发生变动就执行动作,我这边设置为 <code>push</code> 的 <code>hexo</code> 分支,意为当 <code>hexo</code> 分支下发生了 <code>push</code> 动作后就执行此 <code>action</code> ,分支名请填自己仓库实际的,是 <code>main</code>还是 <code>hexo</code> 请根据实际选择。</p><p><code>jobs</code> 下的名称大概是实际执行 <code>action</code> 时的名字,可写个便于理解的名字。</p><p><code>runs-on</code> 是声明需要什么类型的机器, <code>ubuntu-latest</code> 就是申请最新的 <code>ubuntu</code> 系统的机子。</p><p><code>fail-fast</code> 的实际用途我也不懂,反正他就在那儿了.jpg 。</p> <figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="attr">steps:</span> </span><br><span class="line"><span class="bullet">-</span> <span class="attr">uses:</span> <span class="string">actions/checkout@v2</span> <span class="comment">#拉取仓库文件</span></span><br><span class="line"></span><br><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Set</span> <span class="string">up</span> <span class="string">Node.js</span></span><br><span class="line"> <span class="attr">uses:</span> <span class="string">actions/setup-node@v1</span></span><br><span class="line"> <span class="attr">with:</span></span><br><span class="line"> <span class="attr">node-version:</span> <span class="number">17</span></span><br><span class="line"> </span><br><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Install</span> <span class="string">dependencies</span></span><br><span class="line"> <span class="attr">run:</span> <span class="string">|</span></span><br><span class="line"><span class="string"> npm install -g hexo-cli</span></span><br><span class="line"><span class="string"> npm install</span></span><br><span class="line"><span class="string"> git config --global user.name &quot;wherever&quot;</span></span><br><span class="line"><span class="string"> git config --global user.email &quot;wherever@xxx.xx&quot;</span></span><br><span class="line"><span class="string"></span><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Deploy</span></span><br><span class="line"> <span class="attr">env:</span></span><br><span class="line"> <span class="attr">DEPLOY_KEY:</span> <span class="string">$&#123;&#123;</span> <span class="string">secrets.HEXO_DEPLOY</span> <span class="string">&#125;&#125;</span></span><br><span class="line"> <span class="attr">run:</span> <span class="string">|</span></span><br><span class="line"><span class="string"> hexo clean</span></span><br><span class="line"><span class="string"> hexo generate</span></span><br><span class="line"><span class="string"> cd ./public</span></span><br><span class="line"><span class="string"> git init</span></span><br><span class="line"><span class="string"> git add --all .</span></span><br><span class="line"><span class="string"> git commit -m &quot;GitHub action Auto Builder&quot;</span></span><br><span class="line"><span class="string"> git push --quiet --force https://$DEPLOY_KEY@github.com/name/name.github.io.git master</span></span><br><span class="line"><span class="string"></span></span><br></pre></td></tr></table></figure><p>之后就是 <code>steps</code> 栏目了,<code>name</code> 写个便于理解的名字。</p><p><code>GitHub actions</code> 最为被称道的一点就是能用其他人预先写好的脚本,所以在 <code>Set up Node.js</code> 栏里的 <code>actions/setup-node@v1</code> 这里就是引用了安装 <code>nodejs</code> 环境的脚本,<code>with</code> 后面填入脚本里预先定义好的变量(填 17 意为安装版本号为 17 的 <code>node</code> ),不用自己考虑如何实现。</p><p><code>Install dependencies</code> 这栏就是安装依赖了,<code>npm</code> 安装 <code>Hexo</code> 的包,然后 <code>git config</code> 是设置自己的名称和电子邮箱。</p><p><code>Deploy</code> 的 <code>env</code> 一栏就是上面设置 <code>Actions secrets</code> 操作起到用处的地方了,</p><p><code>DEPLOY_KEY: $&#123;&#123; secrets.HEXO_DEPLOY &#125;&#125;</code> </p><p>的意思就是把 <code>Actions secrets</code> 里的叫 <code>HEXO_DEPLOY</code> 的值声明成叫 <code>DEPLOY_KEY</code> 的环境变量,按自己实际情况写……</p><p>下面的命令就是重复流水帐了…… <code>git push --quiet --force https://$DEPLOY_KEY@github.com/name/name.github.io.git master</code> 这里就根据实际情况写了,我是博客源文件和生成的静态文件都放一个仓库里就将生成好的静态文件用 <code>--force</code> 参数强制部署到 <code>master</code> 分支,<strong>要提前切换好分支!</strong>在自己仓库的 <code>Settings -&gt; Branches</code> 的 <code>Default branch</code> 里将自己放置博客源代码的分支改名并设为默认(我是将放博客源代码的命名为 <code>hexo</code>),请提前确认好,要不然 <code>--force</code> 参数将会连同历史记录<strong>覆盖</strong>掉 <code>master</code> 分支的内容!</p><p>如果是分出一个仓库放置生成后的静态页面就根据自己实际情况写。</p><h3 id="测试"><a href="#测试" class="headerlink" title="测试"></a>测试</h3><p>之后就是进行 <code>push</code> 操作看看 <code>action</code> 有没有正常工作了,要是失败就会出现红色的叉叉,这时请根据提示检查哪里出了问题(文件缩进、名称没写对等……)。</p><p>成功了的话,就去检查对应分支有没有出现对应的静态文件了。</p><h2 id="部署自定义字体"><a href="#部署自定义字体" class="headerlink" title="部署自定义字体"></a>部署自定义字体</h2><p>当然……因为是一台对应的机器,所以可以装点 <code>Python</code> 环境运行一点脚本啊……我之前<a href="../../../2021/03/%E4%B8%AD%E6%96%87%E7%BD%91%E9%A1%B5%E5%AD%97%E4%BD%93%E5%8A%A8%E6%80%81%E8%A3%81%E5%89%AA/">中文字体动态剪裁</a>就是用 <code>GitHub actions</code> 执行的。</p><h3 id="具体而言……"><a href="#具体而言……" class="headerlink" title="具体而言……"></a>具体而言……</h3><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">steps:</span> <span class="comment">#安装 Python 环境</span></span><br><span class="line"><span class="bullet">-</span> <span class="attr">uses:</span> <span class="string">actions/checkout@v2</span></span><br><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Set</span> <span class="string">up</span> <span class="string">Python</span> <span class="number">3.9</span></span><br><span class="line"> <span class="attr">uses:</span> <span class="string">actions/setup-python@v2</span></span><br><span class="line"> <span class="attr">with:</span></span><br><span class="line"> <span class="attr">python-version:</span> <span class="number">3.9</span></span><br><span class="line"> </span><br><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Install</span> <span class="string">dependencies</span></span><br><span class="line"> <span class="attr">run:</span> <span class="string">|</span></span><br><span class="line"><span class="string"> python -m pip install --upgrade pip</span></span><br><span class="line"><span class="string"> python -m pip install fonttools brotli requests</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Deploy</span></span><br><span class="line"> <span class="attr">run:</span> <span class="string">|</span></span><br><span class="line"><span class="string"> python3 utils.py -d #运行提前写好的脚本生成字符集</span></span><br><span class="line"><span class="string"> pyftsubset Zpix.ttf --text-file=strdb.txt #裁剪</span></span><br><span class="line"><span class="string"> fonttools ttLib.woff2 compress -o Zpix.woff2 Zpix.subset.ttf</span></span><br><span class="line"><span class="string"> mv Zpix.woff2 ./public/css/fonts</span></span><br><span class="line"><span class="string"> mv Zpix.subset.ttf ./public/css/fonts/Zpix.ttf #将裁剪好的文件放到生成文件夹内</span></span><br></pre></td></tr></table></figure><h2 id="初始化-Giscus-对应评论"><a href="#初始化-Giscus-对应评论" class="headerlink" title="初始化 Giscus 对应评论"></a>初始化 Giscus 对应评论</h2><h3 id="脚本文件"><a href="#脚本文件" class="headerlink" title="脚本文件"></a>脚本文件</h3><p><a href="../../01/%E4%B8%BA%E5%8D%9A%E5%AE%A2%E6%94%AF%E6%8C%81%E8%AF%84%E8%AE%BA%E7%B3%BB%E7%BB%9F/">参考这</a>。</p><h3 id="配置文件"><a href="#配置文件" class="headerlink" title="配置文件"></a>配置文件</h3><p><a href="https://github.com/SouthFox-D/SouthFox-D.github.io/blob/hexo/.github/workflows/deploy.yml">参考这</a>……</p><h2 id="图片备份"><a href="#图片备份" class="headerlink" title="图片备份"></a>图片备份</h2><p>虽然博客用了 <a href="/2022/03/IPFS%E5%92%8C%E5%8D%9A%E5%AE%A2/"><code>IPFS</code></a> 来当博客图床,但是也有失效的风险,所以做好备份是肯定的啦~</p><h3 id="脚本文件-1"><a href="#脚本文件-1" class="headerlink" title="脚本文件"></a>脚本文件</h3><p>跟<a href="../IPFS%E5%92%8C%E5%8D%9A%E5%AE%A2/">本地版</a>的区别不大,就是将图片放到一个文件夹方便后续操作……</p><p><a href="https://github.com/SouthFox-D/SouthFox-D.github.io/blob/hexo/utils.py">如果真想看……</a></p><h3 id="配置文件-1"><a href="#配置文件-1" class="headerlink" title="配置文件"></a>配置文件</h3><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">steps:</span></span><br><span class="line"><span class="bullet">-</span> <span class="attr">uses:</span> <span class="string">actions/checkout@v2</span> <span class="comment"># 安装 Python 环境</span></span><br><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Set</span> <span class="string">up</span> <span class="string">Python</span> <span class="number">3.9</span></span><br><span class="line"> <span class="attr">uses:</span> <span class="string">actions/setup-python@v2</span></span><br><span class="line"> <span class="attr">with:</span></span><br><span class="line"> <span class="attr">python-version:</span> <span class="number">3.9</span></span><br><span class="line"> </span><br><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Install</span> <span class="string">dependencies</span></span><br><span class="line"> <span class="attr">run:</span> <span class="string">|</span></span><br><span class="line"><span class="string"> sudo apt-get install wget</span></span><br><span class="line"><span class="string"> python -m pip install --upgrade pip</span></span><br><span class="line"><span class="string"> python -m pip install fonttools brotli requests</span></span><br><span class="line"><span class="string"> git config --global user.name &quot;SouthFox-D&quot; #自己的……</span></span><br><span class="line"><span class="string"> git config --global user.email &quot;southfoxdreamer@gmail.com&quot;</span></span><br><span class="line"><span class="string"></span><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Check</span> <span class="string">Img</span></span><br><span class="line"> <span class="attr">run:</span> <span class="string">|</span></span><br><span class="line"><span class="string"> wget https://raw.githubusercontent.com/SouthFox-D/blog_img/main/imgList.json #改成自己的仓库并已存在此文件</span></span><br><span class="line"><span class="string"> python3 utils.py -b</span></span><br><span class="line"><span class="string"></span><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Backup</span></span><br><span class="line"> <span class="attr">env:</span></span><br><span class="line"> <span class="attr">DEPLOY_KEY:</span> <span class="string">$&#123;&#123;</span> <span class="string">secrets.HEXO_DEPLOY</span> <span class="string">&#125;&#125;</span> <span class="comment">#自己的……</span></span><br><span class="line"> <span class="attr">run:</span> <span class="string">|</span></span><br><span class="line"><span class="string"> rm -rf .git #删除 Hexo 的 .git 文件夹防止后续冲突</span></span><br><span class="line"><span class="string"> git clone https://github.com/SouthFox-D/blog_img.git blog_img #备份仓库</span></span><br><span class="line"><span class="string"> cp -f newimg/* blog_img/ #合并文件夹</span></span><br><span class="line"><span class="string"> cd blog_img</span></span><br><span class="line"><span class="string"> git add .</span></span><br><span class="line"><span class="string"> git commit -am &quot;Auto backup&quot; || echo &quot;Nothing to push&quot; #防止报错</span></span><br><span class="line"><span class="string"> git push --force https://$DEPLOY_KEY@github.com/SouthFox-D/blog_img.git #根据实际情况而定</span></span><br></pre></td></tr></table></figure><p>具体可<a href="https://github.com/SouthFox-D/SouthFox-D.github.io/blob/hexo/.github/workflows/backup-img.yml">参考这</a>……</p><h2 id="总之"><a href="#总之" class="headerlink" title="总之"></a>总之</h2><p>一次编写后,后续就不用怎么管了,自动化的好处体现出来了……</p><p>我在一台没有安装 <code>Hexo</code> 环境下的机器上写作,到时只要直接 <code>push</code> 就让 <code>GitHub</code> 来完成对应的部署操作了,不必自己安装环境又 <code>clear </code> 啊 <code>g</code> 啊 <code>d</code> 啊的……在移动设备写作可以写好直接复制到 <code>GitHub</code> 网页版里,同时图片也不必当心失效。</p><p>反正……微软!有钱的!嫖起来没负罪感。 </p>]]></content:encoded>
<category domain="https://blog.southfox.me/categories/%E6%8A%80%E6%9C%AF/">技术</category>
<category domain="https://blog.southfox.me/tags/%E6%8A%80%E6%9C%AF/">技术</category>
<comments>https://blog.southfox.me/2022/03/Github-Actions-%E6%B5%85%E5%B0%9D%E8%BE%84%E6%AD%A2/#disqus_thread</comments>
</item>
<item>
<title>IPFS和博客</title>
<link>https://blog.southfox.me/2022/03/IPFS%E5%92%8C%E5%8D%9A%E5%AE%A2/</link>
<guid>https://blog.southfox.me/2022/03/IPFS%E5%92%8C%E5%8D%9A%E5%AE%A2/</guid>
<pubDate>Sun, 06 Mar 2022 14:02:09 GMT</pubDate>
<description>&lt;p&gt;似乎这是两码事?&lt;/p&gt;</description>
<content:encoded><![CDATA[<p>似乎这是两码事?</p><span id="more"></span><h2 id="IPFS"><a href="#IPFS" class="headerlink" title="IPFS"></a>IPFS</h2><p><code>IPFS</code> 全称 <code>InterPlanetary File System</code>),中文名可叫<strong>星际文件系统</strong>。</p><p>这略带一丝中二的名字确实透露了这项目的愿景,设想一下,要是人类真的在太阳系殖民成功了,各个殖民地要如何通信?就算是火星和地球光也要走三分钟,最低<strong>六分钟</strong>的延迟,谁受得了啊?</p><p>但观测一下就可以发现,网络中的很多数据是可以复用的。比如,火星上的 <code>A</code> 访问了地球的今日新闻,火星上的 <code>B</code> 想访问地球的今日新闻网站,还要去跟地球通信吗?他只要跟 <code>A</code> 获取数据就可以了。</p><p>这就是 <code>IPFS</code> 的基本思想了,一个点对点的分布式文件系统。</p><h3 id="能做啥"><a href="#能做啥" class="headerlink" title="能做啥"></a>能做啥</h3><p>作为一个点对点的分布式文件系统,基本功能就是存储文件了,图片、视频、静态网页、<strong>文件夹</strong>皆可。</p><p>文件上传后再经过算mo法后文件会被标上一个类似于 <code>Qmd3oSMoEb3npqXdjwek7RPfvteMckrBFBRHU1ECZDtAEC</code> 这种形式的 <code>CID</code> ,这个 <code>CID</code> 可以唯一标识一个文件,其他人将这个 <code>CID</code> 告诉 <code>IPFS</code> 网络,就可以在全世界的 <code>IPFS</code> 网络中进行获取了。</p><h3 id="网关"><a href="#网关" class="headerlink" title="网关"></a>网关</h3><p>但遗憾的是 <code>IPFS</code> 不能兼容现在主流的 <code>HTTP</code> 网络,如果没有专门的客户端又想要使用 <code>IPFS</code> 网络,要借助一个网关才可以。</p><p>好比如世界上有一群人发明了一种新语言,这种语言甚至需要借助一个新器官才能沟通,很明显其他人是完全无法同使用新语言的人交流的。新语言使用者为了增大影响力,决定派出几名翻译,让双方能够沟通。</p><blockquote><p> 可通过<a href="https://ipfs.github.io/public-gateway-checker/">公共网关检查站</a>获知常见公共网关。</p><p>国内访问优秀的网关为:</p><p>w3s.link cloudflare-ipfs.com (Cloudflare 我的超人!)</p><p>ipfs.fleek.co</p></blockquote><p>在网关后面加上 <code>/ipfs/[cid]</code> 即可通过 <code>http</code> 的形式获取文件了。</p><p>试试看↓:</p><p><code>/ipfs/Qmd3oSMoEb3npqXdjwek7RPfvteMckrBFBRHU1ECZDtAEC </code></p><ul><li><p><a href="https://media.southfox.me/ipfs/Qmd3oSMoEb3npqXdjwek7RPfvteMckrBFBRHU1ECZDtAEC">w3s.link</a></p></li><li><p><a href="https://ipfs.fleek.co/ipfs/Qmd3oSMoEb3npqXdjwek7RPfvteMckrBFBRHU1ECZDtAEC">ipfs.fleek.co</a></p></li></ul><h3 id="IPNS"><a href="#IPNS" class="headerlink" title="IPNS"></a>IPNS</h3><p><code>cid</code> 形式有个问题就是他是根据文件内容进行计算的,文件内容哪怕改动一个字,生成的 <code>cid</code> 也会完全不同……如果要在 <code>IPFS</code> 网络部署一个网站的话,管理员每次更新网站,就得把新 <code>cid</code> 重新告知出去吗?</p><p>显然太折腾了……但可以利用现有的 <code>DNS</code> ,将 <code>cid</code> 绑定到 <code>DNS</code> 上,这样管理方仅需更新 <code>DNS</code> 即可。这种方式被成为 <code>IPNS</code> ( InterPlanetary Name System) 。</p><p>通过这种方式,可以将一个静态网站托管到 <code>IPFS</code> 网络上面,生命力大大增强。</p><p>一般网关也支持 <code>IPNS</code> 形式访问,在网关后面加上 <code>/ipns/[域名]</code> 即可。</p><p>试试看↓:</p><p><code>/ipns/zh.wikipedia-on-ipfs.org</code> (一个静态的维基百科存档)</p><ul><li><a href="https://w3s.link/ipns/zh.wikipedia-on-ipfs.org">w3s.link</a></li><li><a href="https://ipfs.fleek.co/ipns/zh.wikipedia-on-ipfs.org">ipfs.fleek.co</a></li></ul><p><code>/ipns/blog.southfox.me</code> (当然!)</p><ul><li><a href="https://w3s.link/ipns/blog.southfox.me">w3s.link</a></li><li><a href="https://ipfs.fleek.co/ipns/blog.southfox.me">ipfs.fleek.co</a></li></ul><h2 id="IPFS-图床"><a href="#IPFS-图床" class="headerlink" title="IPFS 图床"></a>IPFS 图床</h2><p>那么托管文件,最容易想到的就是图片了,本博客的图片也在几个月前迁移到了 <code>IPFS</code> 网络上。</p><p>如果真想将图片放到 <code>IPFS</code> 上,那么该考虑以下事情:</p><p><strong>优点:</strong></p><ul><li><p>抗☐☐,即使一个网关炸掉了,也可以切换另一个网关。</p></li><li><p>轻松切换, 文件 <code>cid</code> 是不变的,<code>VS Code</code> 全文替换就可以很轻松切到另一个网关,不像一般图床,其连接是随机的,其迁移成本会变得非常大。</p></li></ul><p><strong>缺点:</strong></p><ul><li>慢……速度一般来说只能说凑合,除非将设置一个靠近用户的位置放置网关,同时文件刚好就在这网关上……</li></ul><h3 id="web3-storage"><a href="#web3-storage" class="headerlink" title="web3.storage"></a>web3.storage</h3><p><a href="https://web3.storage/">地址</a></p><p>可使用 <code>GitHub</code> 注册,这网站提供 <code>1T</code> 的存储空间。</p><h3 id="fleek-co"><a href="#fleek-co" class="headerlink" title="fleek.co"></a>fleek.co</h3><p><a href="https://fleek.co/">地址</a></p><p>同样可使用 <code>GitHub</code> 注册,可提供存储空间不明。</p><p>但是重点是!他提供<strong>网站托管</strong></p><h3 id="Pinata"><a href="#Pinata" class="headerlink" title="Pinata"></a>Pinata</h3><p><a href="pinata.cloud">地址</a></p><p><code>1G</code> 免费空间……但似乎是 <code>IPFS</code> 客户端能直接连接过去进行备份?总之不推荐(因为空间太小了)。</p><h3 id="公共网关"><a href="#公共网关" class="headerlink" title="公共网关"></a>公共网关</h3><p>以上的网站是要自己手动上传至他们的网页,并没有很好的支持 <code>HTTP API</code> ,所以喜欢用 <code>PicGo</code> 传图并直接获取 <code>MarkDown</code> 连接的懒人可能要寻找能够直接传图的公共网关了。</p><h4 id="PicGo"><a href="#PicGo" class="headerlink" title="PicGo"></a>PicGo</h4><p>在插件市场搜索 <code>web-uploader-custom-url-prefix</code> 并进行安装,配置成如下:</p><p><img src="https://media.southfox.me/ipfs/Qma7FSQ3tzoT8LqLxMRKVVJ5cNSEu3HgKL1aXPzAYTzXmV"></p><p>其中 <code>infura-ipfs.io</code> 可以是任意支持 <code>HTTP API </code> 形式上传的网关。</p><p>自定义图片前缀可以是任意访问速度快的网关。</p><h4 id="Python"><a href="#Python" class="headerlink" title="Python"></a>Python</h4><p>想用 <code>Python</code> 折腾?好主意,所以快去折腾吧!</p><h4 id="快捷命令"><a href="#快捷命令" class="headerlink" title="快捷命令"></a>快捷命令</h4><p>没用过苹果设备,不清楚。</p><p>不过一般参照之前经验改改应该不难……?</p><h2 id="Pin-与失效"><a href="#Pin-与失效" class="headerlink" title="Pin 与失效"></a>Pin 与失效</h2><p>前面的 <code>PicGo</code> 上传图片时带有个 <code>pin=true</code> 参数,这个参数就是告诉网关,这个文件很重要,请不要当成缓存清除。</p><p>因为 <code>IPFS</code> 的设置是,其他节点获取了一个文件后,会放在缓存里,如果服务器的缓存超过了阈值(默认 <code>10G</code>),就会清理掉……</p><p>如果上传文件的服务器下线了,那么还是有可能从缓存了这文件的服务器获取文件的。但万一时间太过久远,久到主服务器不存在,其他服务器缓存早已清理,那么这个文件就如同 <code>BiTorrent</code> 下载中的<strong>死种</strong>一样,再也不能获取了……</p><p>而另一面讲,如果文件很热门,比如明星艳照,那么这个文件将会持久存在,删除不能……所以,<strong>不要向 <code>IPFS</code> 上传个人隐私相关文件!</strong>一旦传播开来,那就没有后悔药了……</p><h2 id="备份"><a href="#备份" class="headerlink" title="备份"></a>备份</h2><p>所以为了数据安全考虑,放置在 <code>IPFS</code> 上的图片也要做好备份……</p><p>似乎可以写个脚本,自动分析文件下的 <code>cid</code> ,然后自动爬取备份到本地。</p><p><del>以后再摸吧。</del></p><p><strong>3-13 更新:</strong></p><p>其实当天就摸了……只是我憋着不放呢。(</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> sys</span><br><span class="line"><span class="keyword">import</span> os</span><br><span class="line"><span class="keyword">import</span> requests</span><br><span class="line"><span class="keyword">import</span> json</span><br><span class="line"><span class="keyword">import</span> re</span><br><span class="line"><span class="keyword">import</span> random</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">backupImg</span>():</span><br><span class="line"> path = os.getcwd()</span><br><span class="line"> <span class="keyword">for</span> root, dirs, files <span class="keyword">in</span> os.walk(path + <span class="string">&#x27;/source&#x27;</span>): <span class="comment">#根据实际情况定</span></span><br><span class="line"> <span class="keyword">for</span> name <span class="keyword">in</span> files :</span><br><span class="line"> filelist.append(os.path.join(root, name))</span><br><span class="line"></span><br><span class="line"> nowImgList = []</span><br><span class="line"> <span class="keyword">for</span> filename <span class="keyword">in</span> filelist:</span><br><span class="line"> <span class="keyword">if</span> filename.endswith(<span class="string">&#x27;.md&#x27;</span>):</span><br><span class="line"> <span class="keyword">if</span> <span class="string">&quot;_posts/&quot;</span> <span class="keyword">in</span> filename:</span><br><span class="line"> post = filename.split(<span class="string">&quot;_posts/&quot;</span>)[-<span class="number">1</span>]</span><br><span class="line"></span><br><span class="line"> <span class="keyword">with</span> <span class="built_in">open</span>(filename, <span class="string">&quot;r&quot;</span>, encoding=<span class="string">&#x27;utf-8&#x27;</span>) <span class="keyword">as</span> f:</span><br><span class="line"> mdText = f.read()</span><br><span class="line"> result = re.findall(<span class="string">&#x27;!\[(.*?)\]\((.*?)\)&#x27;</span>, mdText)</span><br><span class="line"></span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="built_in">len</span>(result)):</span><br><span class="line"> img_quote = result[i][<span class="number">0</span>]</span><br><span class="line"> img_url = result[i][<span class="number">1</span>]</span><br><span class="line"> nowImgList.append(img_url)</span><br><span class="line"></span><br><span class="line"> downLoadList = <span class="built_in">list</span>(<span class="built_in">set</span>(nowImgList).difference((<span class="built_in">set</span>(imgJson[<span class="string">&quot;img&quot;</span>]))))</span><br><span class="line"> <span class="keyword">if</span> downLoadList != <span class="string">&#x27;&#x27;</span>:</span><br><span class="line"> nowImgJson = &#123;&#125;</span><br><span class="line"> nowImgJson[<span class="string">&quot;img&quot;</span>] = nowImgList</span><br><span class="line"> <span class="keyword">with</span> <span class="built_in">open</span>(<span class="string">&#x27;./imgList.json&#x27;</span>, <span class="string">&#x27;w&#x27;</span>, encoding=<span class="string">&#x27;utf-8&#x27;</span>) <span class="keyword">as</span> f:</span><br><span class="line"> json.dump(nowImgJson, f)</span><br><span class="line"></span><br><span class="line"> downloadImg(downLoadList)</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">downloadImg</span>(<span class="params">imgList</span>): </span><br><span class="line"> <span class="keyword">for</span> img_url <span class="keyword">in</span> imgList:</span><br><span class="line"> <span class="keyword">if</span> img_url == <span class="string">&#x27;&#x27;</span>: <span class="comment">#判空</span></span><br><span class="line"> <span class="keyword">continue</span></span><br><span class="line"> <span class="comment"># img name spell</span></span><br><span class="line"> urlname = img_url.split(<span class="string">u&quot;/&quot;</span>)</span><br><span class="line"> img_name = <span class="built_in">str</span>(urlname[-<span class="number">1</span>])</span><br><span class="line"> <span class="comment"># download img</span></span><br><span class="line"> ipfs_gateWay = [<span class="string">&#x27;https://media.southfox.me/ipfs/&#x27;</span>, <span class="string">&#x27;https://ipfs.io/ipfs/&#x27;</span>, <span class="string">&#x27;https://ipfs.fleek.co/ipfs/&#x27;</span>]</span><br><span class="line"> <span class="keyword">if</span> <span class="string">&#x27;ipfs&#x27;</span> <span class="keyword">in</span> img_url:</span><br><span class="line"> img_url = random.choice(ipfs_gateWay) + img_name</span><br><span class="line"></span><br><span class="line"> response = requests.get(img_url) <span class="comment">#根据自己图床链接进行选择</span></span><br><span class="line"> <span class="built_in">print</span>(<span class="string">&#x27;Download &#x27;</span> + img_url + <span class="string">&#x27;✔️&#x27;</span>)</span><br><span class="line"> <span class="comment"># write to file</span></span><br><span class="line"> f_img = <span class="built_in">open</span>(<span class="string">&#x27;./&#x27;</span> + img_name, <span class="string">&#x27;wb&#x27;</span>)</span><br><span class="line"> f_img.write(response.content)</span><br><span class="line"> f_img.close()</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">&#x27;__main__&#x27;</span>:</span><br><span class="line"> filelist = []</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> os.path.exists(<span class="string">&#x27;./imgList.json&#x27;</span>):</span><br><span class="line"> imgJson = []</span><br><span class="line"> <span class="keyword">with</span> <span class="built_in">open</span>(<span class="string">&#x27;./imgList.json&#x27;</span>, <span class="string">&#x27;r&#x27;</span>, encoding=<span class="string">&#x27;utf-8&#x27;</span>) <span class="keyword">as</span> f:</span><br><span class="line"> imgJson = json.load(f)</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> imgJson = &#123;&#125;</span><br><span class="line"> imgJson[<span class="string">&quot;img&quot;</span>] = []</span><br><span class="line"> backupImg()</span><br></pre></td></tr></table></figure><p>简单来说,就是用扫描 <code>source</code> 目录下的的 <code>.md</code> 文件,并用正则扫描 <code>![]()</code> 这种形式的图片语法并存起来。</p><p>然后进行图片抓取,其中 <code>if &#39;ipfs&#39; in img_url:</code> 这里是判断链接是否是 <code>ipfs</code> 的图床链接,要是你的图片链接只来源一个图床(例如 <code>sm.ms</code> 可以写 <code>if &#39;loli.net&#39; in img_url:</code>),请自行替换,要是图床来源杂乱就……不进行判断抓取下来自己手动选择吧。</p><p>然后结束后会生成一个 <code>imgList.json</code> 文件,里面是已经抓取的图片,以后要是再进行抓取的话就通过这文件和新扫描的文件列表做集合的求差处理(<code>downLoadList = list(set(nowImgList).difference((set(imgJson[&quot;img&quot;]))))</code>),以来判断要新抓取那些文件……</p><p><del>总之写的非常初学者……应该都是比较好理解的吧(</del></p><p>很多都是为了 <code>GitHub Actions</code> 准备的,不知道是什么的话可以看<a href="../Github-Actions-%E6%B5%85%E5%B0%9D%E8%BE%84%E6%AD%A2">这</a>。</p><h2 id="IPFS-博客"><a href="#IPFS-博客" class="headerlink" title="IPFS 博客"></a>IPFS 博客</h2><p>如果你有一个静态博客,为何不考虑放置在 <code>IPFS</code> 网络上呢?</p><p>首先要更改的就是博客的连接……要前往博客模板把其里面的所有连接都改成<strong>相对连接</strong>的形式,否则托管时会根本加载不了 <code>css</code> 或者 <code>js</code> 文件。</p><p>接着前往 <a href="https://fleek.co/">fleek</a> 并注册,然后在托管一栏中选择你放置静态网页的仓库(或分支),就能简单的部署到 <code>IPFS</code> 网络上了,要是想启用 <code>IPNS</code> ,也可以在 <code>SETTINGS -&gt; Domain Management -&gt; Add Custom Domain</code> 增加一个博客域名,然后在新增域名的更多选项里选择 <code>Dns Link</code> ,会自动弹出个窗口绑定域名。把这个 <code>CNAME</code> 选项绑定到你的域名管理商即可。(<code>Cloudflare</code> 我默认关了代理,要是绑定迟迟不能生效的话可以试着关掉 <code>Cloudflare</code> 代理试试)</p><h2 id="实际使用"><a href="#实际使用" class="headerlink" title="实际使用"></a>实际使用</h2><h3 id="客户端"><a href="#客户端" class="headerlink" title="客户端"></a>客户端</h3><p><a href="https://github.com/ipfs/ipfs-desktop">客户端下载地址</a></p><p>不一定需要个网关,实际自己直接用用也是不错的,就是使用时会不停的交换数据,对电量和流量的消耗也很大……如果所在网络对 <code>P2P</code> 协议限制比较严格那可就要小心了……</p><h3 id="服务端"><a href="#服务端" class="headerlink" title="服务端"></a>服务端</h3><p><a href="https://github.com/ipfs/go-ipfs">服务端下载地址</a></p><p>如果你手头上有闲置的服务器,为什么不尝试部署一个 <code>IPFS</code> 服务呢?</p><p>将文件放一份备份在自己的服务器上,或是搭建一个自用网关,也能有效提升使用体验(当然要服务器性能足够)。</p><h2 id="文件币"><a href="#文件币" class="headerlink" title="文件币"></a>文件币</h2><p>哦……所以还是谈论到这个话题了……</p><p><code>filecoin</code> ,是一个建立在 <code>IPFS</code> 上的加密货币项目(大概)?</p><p>只要你抵押出相当容量的硬盘,就能进行挖矿了……这似乎也是去年硬盘涨价风潮原因之一?<del>(那更该用了,这是拿大众的钱买硬盘啊)</del></p><p>但现在这币似乎状态不好的样子,价格跌倒了顶值的十分之一。虽然我对加密货币不感冒,但我还是想 <code>fil</code> 涨起来的,毕竟币涨了也是能吸引更多人提供存储空间的,经营托管服务的服务商也能通过 <code>fil</code> 进行回本。</p><p>但是不考虑加密货币也罢, <code>IPFS</code> 做为一个开源项目,如果其足够好,也能自己证明自己,<code>IPFS</code> 能取代 <code>HTTP</code> 成为下一代网络标准吗?天知道。</p>]]></content:encoded>
<category domain="https://blog.southfox.me/categories/%E6%8A%80%E6%9C%AF/">技术</category>
<category domain="https://blog.southfox.me/tags/%E6%8A%80%E6%9C%AF/">技术</category>
<category domain="https://blog.southfox.me/tags/IPFS/">IPFS</category>
<comments>https://blog.southfox.me/2022/03/IPFS%E5%92%8C%E5%8D%9A%E5%AE%A2/#disqus_thread</comments>
</item>
<item>
<title>22年2月梦记</title>
<link>https://blog.southfox.me/2022/02/22%E5%B9%B42%E6%9C%88%E6%A2%A6%E8%AE%B0/</link>
<guid>https://blog.southfox.me/2022/02/22%E5%B9%B42%E6%9C%88%E6%A2%A6%E8%AE%B0/</guid>
<pubDate>Sun, 13 Feb 2022 01:58:16 GMT</pubDate>
<description>&lt;p&gt;该记了!&lt;/p&gt;
&lt;p&gt;以后还是多写点解析吧……要不然过个两三年再回来看,肯定就不知道是什么意思了。&lt;/p&gt;</description>
<content:encoded><![CDATA[<p>该记了!</p><p>以后还是多写点解析吧……要不然过个两三年再回来看,肯定就不知道是什么意思了。</p><span id="more"></span><h2 id="2-12"><a href="#2-12" class="headerlink" title="2.12"></a>2.12</h2><p>晚 普</p><h3 id="列车"><a href="#列车" class="headerlink" title="列车"></a>列车</h3><p>我在一座列车上,车厢不是车厢,而是一个又一个场景……</p><p>前几个场景不记得了,中间有个场景好像是我在一个楼梯上。因为背包里的书非常重,我就把他放在楼梯上,而我在一旁喘气……背包里的书似乎都没有封面的样子。楼梯上方似乎是一个幼儿教室的样子……</p><blockquote><p>喂,你带回来的资料书该看了,要不然带回来到底要干嘛?</p></blockquote><p>下一个场景是我在一家卖场里,带有科技感的四边形柱子悬在上方,我来到一个玻璃展柜前,似乎想要买,但是拿起来之后,还是放下,最后打算不买了。</p><p>最后一个场景似乎我下站了,我打开地图,发现我竟然在目的地反方向!我急忙问车站人员,得到答案我已经过了好多站了……我拿出手机,不是惯用手机,似乎是苹果的?我打开手机开始打字,输入法非常别扭,我连连打错,窘迫的不行。最后觉得这样子还不如……醒来……</p><p>然后我就醒了。</p><h2 id="2-16"><a href="#2-16" class="headerlink" title="2.16"></a>2.16</h2><p>中 普</p><h3 id="开包"><a href="#开包" class="headerlink" title="开包"></a>开包</h3><p>我似乎有类似 jojo 布姐那样的能力,在任何事物上开拉链。</p><p>我在街上对着行道树干上使用了能力,然后……这拉链是明日方舟抽卡!我就对着一棵树抽起卡来,抽了似乎很多次。树伤痕累累……汁液滴的到处都是,之后就有管理人员过来,想要制裁我,他查看了树干,记下了三条拉链痕迹(其实还有很多!),我心里想着……至于吗……就这点小事就要把我关那么久?</p><blockquote><p>氪金抽卡手游,恶心啊!</p></blockquote><h2 id="2-17"><a href="#2-17" class="headerlink" title="2.17"></a>2.17</h2><p>中 普</p><h3 id="意外的联络"><a href="#意外的联络" class="headerlink" title="意外的联络"></a>意外的联络</h3><p>一个很久没联系的初中同学找上了我的 QQ ,然后给我发消息,说我的长毛象 ID 是这个,快来加我……</p>]]></content:encoded>
<category domain="https://blog.southfox.me/categories/%E6%A2%A6%E8%AE%B0/">梦记</category>
<category domain="https://blog.southfox.me/tags/%E6%A2%A6%E8%AE%B0/">梦记</category>
<comments>https://blog.southfox.me/2022/02/22%E5%B9%B42%E6%9C%88%E6%A2%A6%E8%AE%B0/#disqus_thread</comments>
</item>
</channel>
</rss>