<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>喃小柯站</title>
	<atom:link href="https://www.manshaoco.com/feed" rel="self" type="application/rss+xml" />
	<link>https://www.manshaoco.com</link>
	<description>点滴，就在脚下</description>
	<lastBuildDate>Mon, 06 Apr 2026 07:13:53 +0000</lastBuildDate>
	<language>zh-Hans</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://www.manshaoco.com/wp-content/uploads/2022/05/cropped-喃小柯站-新Icon-32x32.png</url>
	<title>喃小柯站</title>
	<link>https://www.manshaoco.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>下载指定旧版本 iOS App 的小记</title>
		<link>https://www.manshaoco.com/1397.html</link>
					<comments>https://www.manshaoco.com/1397.html#comments</comments>
		
		<dc:creator><![CDATA[Fotink]]></dc:creator>
		<pubDate>Fri, 03 Apr 2026 02:59:46 +0000</pubDate>
				<category><![CDATA[教程]]></category>
		<guid isPermaLink="false">https://www.manshaoco.com/?p=1397</guid>

					<description><![CDATA[写在开头 问：为什么要下载旧版本 iOS App？ 答：部分应用的旧版本无广告；无内购订阅；老设备运行更流畅。 [&#8230;]]]></description>
										<content:encoded><![CDATA[<div id="core-ai-summary-tool"></div><h1>写在开头</h1>
<p><strong>问：为什么要下载旧版本 iOS App？</strong><br />
答：部分应用的旧版本无广告；无内购订阅；老设备运行更流畅。</p>
<p>众所周知，iOS / iPadOS 端的应用来源，绝大部分来自苹果官方的 App Store，想要寻找一个特定版本的 App，比 Android 端难多了。主流应用可以在 i4 之类的工具或网站上找到，但小众应用就没办法了。</p>
<p>本文将使用开源工具 <a href="https://github.com/majd/ipatool" title="IPATool">IPATool</a>，搭配三方应用历史版本ID查询工具，实现将上架于 App Store 的应用的指定版本保存至本地，从而安装旧版本应用。</p>
<h1>准备工作</h1>
<p>1、<strong>IPATool</strong>（<a href="https://github.com/majd/ipatool">https://github.com/majd/ipatool</a>）</p>
<ul>
<li>适用于 Windows / macOS / Linux</li>
</ul>
<p>2、<strong>历史版本查询工具</strong>（任选一个即可）</p>
<ul>
<li>三方在线工具（<a href="https://app.agzy.cn/index.html">https://app.agzy.cn/index.html</a>）</li>
<li>三方在线工具（<a href="https://appstore.bilin.eu.org/">https://appstore.bilin.eu.org/</a>）</li>
<li>三方 Windows 工具，可配合旧版本 iTunes 直接完成下载，详情看链接（<a href="https://www.bilibili.com/read/readlist/rl801601">https://www.bilibili.com/read/readlist/rl801601</a>）</li>
</ul>
<p>3、<strong>爱思助手</strong>（用来安装 .ipa 格式的安装包，别的替代品也行）</p>
<h1>方法流程</h1>
<p>1、寻找对应的App，获取<strong>&lt;应用ID&gt;</strong>、<strong>&lt;版本ID&gt;</strong></p>
<ul>
<li>其中 <strong>&lt;应用ID&gt;</strong> 可通过搜索引擎搜索“<strong>应用名 App Store</strong>”关键词，找到对应的 App Store 网页，通过链接结尾的“<strong>id&lt;应用ID&gt;</strong>”部分得到</li>
</ul>
<p>2、安装 IPATool，macOS 拥有 Homebrew 可直接使用下列终端命令安装；Windows 和 Linux 可通过上面的 GitHub 链接获取最新的 Release 可执行文件，使用终端切入对应目录，直接执行步骤 3 的命令</p>
<pre><code class="prettyprint"  class="language-bash">brew install ipatool</code></pre>
<p>3、终端依次执行下列 IPATool 命令</p>
<pre><code class="prettyprint"  class="language-bash"># 登录自己的 Apple ID
ipatool auth login -e &lt;邮箱&gt; -p &lt;密码&gt;

# 保存指定版本的应用至本地
ipatool download -i &lt;应用ID&gt; --external-version-id &lt;版本ID&gt; -o &lt;保存的路径和文件名&gt;</code></pre>
<p>4、使用爱思等工具，将下载的 .ipa 安装至设备即可。</p>
<h1>参考文章</h1>
<p><a href="https://www.bilibili.com/opus/1045899823080800264">https://www.bilibili.com/opus/1045899823080800264</a></p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.manshaoco.com/1397.html/feed</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>十周年特别篇：我们仍在行进，书写人生的答案</title>
		<link>https://www.manshaoco.com/1361.html</link>
					<comments>https://www.manshaoco.com/1361.html#comments</comments>
		
		<dc:creator><![CDATA[Fotink]]></dc:creator>
		<pubDate>Fri, 02 May 2025 13:18:17 +0000</pubDate>
				<category><![CDATA[随笔]]></category>
		<guid isPermaLink="false">https://www.manshaoco.com/?p=1361</guid>

					<description><![CDATA[不知不觉，喃小柯站（包括它的前身小柯小站）于去年年底成立十年辣！🎉 想了很久，在这个特殊的时间点，还是得写点什 [&#8230;]]]></description>
										<content:encoded><![CDATA[<div id="core-ai-summary-tool"></div><p>不知不觉，喃小柯站（包括它的前身小柯小站）于去年年底<strong>成立十年辣</strong>！🎉</p>
<p>想了很久，在这个特殊的时间点，还是得写点什么纪念一下。</p>
<p>这篇文章<strong>历时大半年</strong>。经过了<strong>不断的完善和修改</strong>，我将全文分为<strong>五个板块</strong>，整体可视为按照时间线叙述（前两个板块算作平行时间线）。文章中难免存在一些不成熟的想法和表述，如果你有更好的看法，欢迎在评论区与我讨论或留言！</p>
<hr />
<h3>Part1:「初学者的幻觉：自娱自乐与意义焦虑」</h3>
<p>真的，这十年，<strong>感觉过的飞快</strong>。</p>
<p>还记得十年前这个时候，我读初一。临近寒假，那时和一位关系很好的老师吹嘘自己搭建的网站和论坛。老师人也很nice，当时一直在夸奖我。</p>
<p><img decoding="async" src="https://img.manshaoco.com/i/2025/05/02/6814c2b1f3827.webp" alt="2015年3月的博客截图" title="%title插图%num" /></p>
<p>老师的夸赞，是出于对学生追求新事物的肯定。但俗话说得好，<strong>物极必反</strong>嘛。在老师的一声声夸奖中，我也逐渐意识到，<strong>那时搭建的这些网站算不了什么</strong>。</p>
<p>一方面是因为我的这些博客和论坛<strong>几乎没有人来访问，纯粹就是自娱自乐</strong>，不过那会儿我没有电子支付工具，所以做网站基本没花钱，那么自娱自乐也就无关紧要了；另一方面是，那时建站工具就<strong>已经越来越“傻瓜化”了</strong>，我的“技术力”不过是照着教程点鼠标，确实没啥技术含量。</p>
<p>所以，在很早的时候，我就在想：怎样才能<strong>做点既对自己，也对他人有意义的事情</strong>？</p>
<p>也许你会觉得，我这个小伙子厉害啊，年纪轻轻时就有这么高的思想觉悟了。但很遗憾的是，<strong>我在此后的一段时间里，并没有找到这个问题的答案</strong>。</p>
<p>看到如今的许多初高中生们，甚至是同龄人，在酷安成为众人追捧的手机 ROM 魔改大神、GitHub 上的手搓 GUI 框架作者，我不由得感慨，<strong>人和人之间的差距还是很明显的</strong>。因为曾经的我，也对 C、Python、手机玩机圈子有着浓厚兴趣，但因探索期的迷茫，既没能在学习上取得一个较好的成绩，也没能在兴趣爱好上取得突出表现。</p>
<p>十年后回看这份遗憾，我依然没有标准答案。但至少，那个在只有一个人的论坛里发着帖子的少年，教会了现在的我一件事：<strong>有些坚持压根不需要观众，因为坚持本身就是答案。</strong> 如果你也在为某些“意义”感到焦虑，不妨记住这句话，再过十年，或许未来的你，也会感激今天的固执。</p>
<hr />
<h3>Part2:「十年挚友的陪伴：网络一线牵，珍惜这份缘」</h3>
<p>我在<a href="https://www.manshaoco.com/about">关于我</a>中提到过好基友 <strong>@Caulic (又名 TKKMKS，花椰菜)</strong>，最早和他相识是在 2014 年 5 月，他在 5qbbs 免费论坛交流群中，私聊我推广他的免费论坛搭建网站。后续可能是年龄相仿，兴趣爱好有很高的重合度，而且我俩都属于好说话的“社牛”，所以一直到现在都还有联系。</p>
<p><img decoding="async" src="https://img.manshaoco.com/i/2025/05/02/6814c1a19ced1.webp" alt="2014年7月的论坛截图" title="%title插图%num" /></p>
<p>仍记得那段时间，由于本人没有网银和支付宝这些在线支付工具，所以网站和域名只能四处“求蹭”。我用过花生壳的免费二级域名，也用过网友手头闲置的域名，直至2014年10月国庆期间，在 Caulic 同学的赞助下，拥有了<strong>第一个域名“sysres.cn”</strong>，且用上了 Caulic 同学购买的 VPS，不再受到免费空间的各种拘束。</p>
<p>可惜好景不长，Caulic 同学购买的 VPS 所在的“母鸡”（实际的服务器）不知为何出现故障，数据全部丢失，没能恢复。这对我来说，就是几个月的心血全都付之东流了。自那之后，我和 Caulic 都认识到：<strong>不要贪便宜，且一定要定期做好数据备份</strong>。</p>
<p>Caulic 同学大我两届，显然比我成熟很多。前些日子整理家里旧硬盘的数据时，我还刚好翻出了以前我俩的聊天记录，才发现那时的自己还是个天真无邪的孩子，和 Caulic 聊的内容带点无厘头和幼稚，说白了就是有点<del>不忍直视</del>。以前总是羡慕别人，现在回想起来，我倒是有点羡慕自己了：<strong>在不知天高地厚的年纪里，就遇到了一个三观正、靠谱的朋友，能被带着一块儿践行兴趣爱好，这实在是太幸运了</strong>。</p>
<p>挚友对我的影响是潜移默化的。除了习惯上的影响（比如我的 <strong>im@fot.ink</strong> 自建域名邮箱就是受他启发，他曾有过 QQ 邮箱差点丢失的经历，自此之后便开始使用自建域名邮箱），还有社团文化的影响。</p>
<p>在我高二时，挚友刚进入大学，我<strong>通过他了解到了大学丰富多彩的社团文化</strong>。当时他加入了计科学院的电脑爱好社团，每周会定期开展解答困惑的志愿活动。那时我所在的高中也有乐器社团、运动社团，却没有电脑爱好社团。正好那时我认识学校团委老师，因此做了一些准备工作后，我就兴冲冲地跑去找团委老师申请开设电脑兴趣社团了。虽然这一过程并不顺利，遇到了团委老师提出的质疑和招新海报的设计问题，但<strong>最终凭借我的志气和个人魅力</strong>，成功说服了团委老师，且请到了我的电脑课老师作为社团指导老师，申请到了每周一次社团活动的机房上机的机会hhh</p>
<p>也是因为这个社团，我认识了 <a href="https://www.zouht.com/"><strong>@ChrisKim</strong></a>，有关他的故事可以另开一篇文章，哈哈哈。</p>
<p>说起这个电脑社的名字，也是很有意思。那时我的想法比较单纯，电脑是发源于国外的产品，咱应该取一个英文名作为社团的名字才比较合适。而想到软件在发布正式版之前的版本号，很多都有 Beta v0.x 的标识，所以我取名为“<strong>Beta 电脑社</strong>”。但在和团委老师协商的过程中，才发现这个名字取的不是很响亮。想到 2016 年 AlphaGo 响彻全球，因此取了“<strong>Alpha 电脑社</strong>”这一名字。后来还打算出过一个社团期刊，名字取名为“<strong>Alpha Tech Striker 科技先锋</strong>”，这一名字实际上受油管知名博主“<strong>Linus Tech Tips</strong>”的影响。虽然后来因为高考和换地上课，期刊没能顺利打印出来分发到各个班级，有点遗憾。</p>
<p><img decoding="async" src="https://img.manshaoco.com/i/2025/05/01/681383a1bfd4a.webp" alt="AlphaTechStriker期刊部分内容图片" title="%title插图%num" /></p>
<p>扯远了，咱们不是在说 Caulic 嘛。直至现在，我和他也还保持联系。</p>
<p>哦对了，2023 年春节过后，咱也是去北京面上基咯，<strong>这真是太酷辣</strong>！</p>
<p><img decoding="async" src="https://img.manshaoco.com/i/2025/05/02/6814c459664ae.webp" alt="跟Caulic面基的说说" title="跟Caulic面基的说说" /></p>
<hr />
<h3>Part3:「大学的转折：认清自我，追寻群策群力」</h3>
<p>好在，咱也是跌跌撞撞进入了大学。</p>
<p>进入大学后，终于<strong>有了更多的契机来发展自己的兴趣爱好</strong>。加入「易航工作室」后，我正式开始学习网站前后端的开发，发现<strong>原来用 HTML+CSS+JS 也能做项目，不是所有的交互式网站都得用 PHP</strong>……</p>
<p>加入学院的科协社团后，认识了如今的好友 <strong>@石fufu和小派蒙</strong> ，在他的协助下，开始着手做专业相关的大创项目和打比赛。刚开始自学单片机时，复现教程的案例成功后，确实会让我有些成就感，但开始做自己的项目，从整合移植他人代码，到自己手搓的这条路，走下来真的很艰难。</p>
<p>固然，“六边形战士”能够更好地适应各种不同的需求。尽可能多地提高自己的技术力，显然会对日后的生活有帮助。但是否真的需要给自己定高标准，追求各方面的全能呢？大学四年走到现在，我逐渐意识到，<strong>人的精力是有限的，人需要认清自己，在合适的时候理应追寻群策群力</strong>。</p>
<p><strong>人的精力是有限的</strong>，这一点不难理解，我也想要通过自己的亲身经历来向你解释我的理解。进入大学后，接触全新的人和事物除了为我带来正向的情绪、认识影响外，也为我带来了一个在那时百思不得其解的困惑：<strong>为什么进入大学，明明没有收获太多成果，但每天都过得很累？</strong>如今站在当下看过去，这个问题可以用“人的精力是有限的”进行解答。首先大一学年确实有不少专业基础课、素质拓展活动、新生教育实践活动需要参加，这已经耗费了不少精力；除此之外，出于个人在新环境中的表现欲，那时几乎所有的小组作业，我都是力争成为组长，主动承担了许多责任外的工作，且没能认识到 <strong>投入越多≠产出越多</strong> 这一道理，导致我在追求细枝末节的内容上耗费了很多不必要的精力。</p>
<p>而<strong>人需要认清自己，在合适的时候理应追寻群策群力</strong>，是我大二学年时比赛的失败经历告诉我的。那时凭借自己在身边的人群里，多会了一点电脑技术而沾沾自喜，看到有“华五机器人”、“智能车”等比赛后，就<strong>盲目组队报名，没有考虑凭借自己拥有的能力和资源，是否能够解决赛题或能否在这一过程中学到新的知识</strong>。结果就是，自己没有任何竞赛经验，没有办法解决赛题，队友的能力也没有得到完全发挥。花费了数周乃至几个月的时间，忙碌于比赛的材料手续、小组会议，最终却没有拿出任何成果。</p>
<p>简言之，当我们身处繁杂事务之中时，理应先对需要处理的事务进行一个重要性、紧急性、投入产出比的排行，然后<strong>将有限的精力，优先投入到重要+紧迫+投入产出比高的事务中</strong>。时刻保持理性思考，很多事情仅通过感性认知，我们会觉得比较急迫。比如在你忙于期末备考时，这时候来了一个同学向你求助一个小问题，你可能会觉得，人家也挺着急，我帮他也就顺手的事。实际情况可能并非”顺手的事“那么简单，一旦你开始帮助，可能才会发现这里面的事情远没有想象的那么容易，很容易一下午就耗费在这样一个小问题上。而在大学里，期末备考的投入产出比是非常高的，在有限的时间里，复习一下午的理工科目例题，可能就足以满足这门课程的及格要求。在答应“顺手的事”之前，进行这样的思考，是很容易看清这其中的利害关系的，从而帮助我们做出理性选择。<strong>认清自己，追寻群策群力</strong>，目的是避免追求自己明明做不到的事情，导致自己明明投入了很多，且感到身心俱疲，却没有得到任何结果。</p>
<p>写完了这一板块，才发现有点偏离博客“十年技术成长路”这一主题，而且聊的话题有点过于严肃了，整的跟写议论文一样。。</p>
<p>（<del>其实我还挺讨厌接受别人的说教来着hhh</del>）</p>
<p>那么接下来我们换个话题，来从这十年里<strong>总结提炼</strong>一点东西吧。</p>
<hr />
<h3>Part4:「做有意义的事：普通人的学习和技术进阶心得」</h3>
<p>如何定义“<strong>有意义的事</strong>”？我想，每个人都有自己的答案。这十年的经历里，我总结出了一些有价值的心得。接下来，我将以<strong>提问-解答</strong>的方式来呈现。如果你也有类似的疑惑，希望能够帮到你。</p>
<h4>Q1：如何坚持“无人问津”的爱好？</h4>
<p>这里的“无人问津”既可以指对于大众而言属实“小众”的兴趣爱好，也可以指在身边的朋友圈中，相对小众但实际上大众化的兴趣爱好。</p>
<p>针对“无人问津”的兴趣爱好，我的看法是，<strong>首先做好自己的本职工作</strong>，无论是学习还是在职工作，<strong>然后放手去做吧</strong>。本职工作是每个人的立身之本，当我们能够”立足“后，兴趣爱好便能起到锦上添花的积极反馈；而如果喧宾夺主（包括我有时候也会这样），将倾注给兴趣爱好的时间大于本职工作，导致本职工作没能做好，那么即使兴趣爱好能够给予我们正向反馈，也不足以抵消本职工作没能做好的负面反馈。</p>
<p>另外，<del>强者大多是孤独的</del>，在变强的路上注定是孤独的，所以不必担心。</p>
<h4>Q2：处理挫败感的技巧有哪些？向上追求的路上，坚持不下去了怎么办？</h4>
<p>多给自己一些积极的心理暗示，比如在手机上设置正能量的桌面小组件、壁纸。</p>
<p>当遇到挫败感 MAX 的事情时，如果不需要立即处理，那就把这事放放，去<strong>做点自己喜欢的事儿（比如洗个澡躺床上看部电影、约好友出去“压马路”，或者<del>游戏里暴揍一顿对面的玩家</del>也中）</strong></p>
<p>向上爬坡的路，必然不是那么容易的，这点众所周知，所以<strong>难免要吃点苦</strong>。但也<strong>记得避免“没苦硬吃”</strong>，生活和做事都讲究一个“追求技巧“，<strong>既让自己过得舒服，又能完成既定目标</strong>才是王道。</p>
<p>备考时的<strong>坐垫、耳机、文具</strong>，用得上的该买就买；坚持不下去了，该出去<strong>散散步、跑圈、举铁</strong>就去。别受<strong>”差生文具多“、”考研人不配休息“</strong>这样的流言的影响。只需要谨记，<strong>把在这条路上的主要任务的优先级置于最高</strong>即可。</p>
<h4>Q3：自学资源推荐</h4>
<p>首先，感谢这个互联网+流媒体+人工智能技术蓬勃发展的时代，这十年来，我的每一处进步都是“<strong>踩在前人的肩上</strong>”才得以实现的。从 2014 年我家接入宽带以来，我自学的这些<strong>计算机、网站建设、编程相关的知识</strong>，80%来自于互联网。最早是<strong>网盘、百度知道+百度经验、吾爱破解论坛</strong>，到后来 <strong>CSDN、博客园、bilibili、知乎</strong>，再到现在的<strong>个人博客、GitHub、Stack Overflow、Reddit</strong> 以及各大<strong>AI工具</strong>，咱们自学的渠道越来越丰富，但信息也越来越繁杂，尤其是<strong>某平台</strong>上的内容信息密度极低，翻了三四篇可能都找不到有参考价值的内容，而且与之关联的<strong>下载站</strong>的<strong>绝大部分文件</strong>，甭管是<strong>垃圾</strong>还是<strong>仅次于垃圾</strong>的文件，都要<strong>付费下载</strong>，属实令人感到愤怒，因此这里分享一下带有我个人偏好的学习方法。</p>
<p>如果想要掌握一门自己从未接触过类似内容的<strong>新的技术</strong>，建议<strong>从视频开始学习</strong>。虽然刷视频学习的效率较低，但新技术本身存在上手门槛，有一个老师傅带学，还是好过自己埋头苦钻。视频网站可以选择 <strong>bilibili</strong>，或者 <strong>YouTube</strong>（可以开启实时转中文的字幕）。如果搜索出来很多相关的视频，不知道该如何选择的话，可以看看评论区，或者去<strong>小红书</strong>搜索一下经验分享；再不济就<del>挨个看一遍</del>，选一个自己看得进去且看着靠谱的。如果已经有了一定的基础，学习一门<strong>类似的新技术</strong>，建议<strong>从该技术的官方手册</strong>，或者<strong>第三方文档、靠谱的经验</strong>开始学习，从新技术的第一个项目开始复刻起，这样能够快速上手，迅速形成自己对该技术的初认知。</p>
<p>如果在后续解决问题时，遇到“<strong>中文搜索无法得到有用的结果</strong>”的情况，我强烈建议你<strong>更换 Google 或 Kagi 这样的搜索引擎，并使用英文关键词搜索你的问题</strong>。例如“<strong>Electron打开开发者工具会报错 Request Autofill.enable failed</strong>”搜不到有用的信息，但“<strong>electron devTools Request Autofill.enable failed</strong>”可以搜索到 GitHub 的 electron 项目中的讨论帖和 StackOverflow 的帖子，很容易发现这是 electron 的已知问题，可以通过关闭自动填充功能以避免报错。</p>
<p>虽说如今很多平台都在推崇“<strong>知识付费</strong>“，但<strong>不是所有知识都值得被拿来包装为付费内容</strong>，每一个学习的人也<strong>并非就能负担得起为知识付费</strong>。所以，如果你需要寻找”<strong>学习版</strong>“资源，包括但不限于<strong>课程、软件</strong>，可以通过<strong>微信</strong>自带的<strong>搜索功能</strong>寻找。这里并非推崇大家都去找盗版，如果在后续，这些知识让你受益良多，软件为你提高了生产力，且有足够的支付能力，那么一定记得要”<strong>补票上车</strong>“嗷。</p>
<p>对了，AI 工具已经能满足很多需求。但我不建议过度依赖AI工具，因为<strong>这可能会让你丧失本该拥有的思考和判断能力</strong>。和上面说到的学习新技术一样，请<strong>避免把 AI 当做权威的老师</strong>，因为 <strong>AI 很可能会犯错，或提供一些过时的技术方法、将简单的任务复杂化</strong>。当你<strong>对某门技术拥有自己的认知后</strong>，再去使用 AI 工具，才能更轻易、更有效地让 AI 工具协助你完成进一步的学习或任务。</p>
<hr />
<h3>Part5:「写在最后：我们仍在行进，书写人生的答案」</h3>
<p>如何定义成功？十年前的那个少年，认为<strong>运营一个访问量破万、SEO 优化到拥有 Alexa 排名的网站</strong>，叫做成功。现在，我的博客日访问量仍然寥寥无几。如果以十年前的评判标准，这十年我在建站方面，是失败的。</p>
<p>但当我收到诸如“<strong>感谢作者，千千静听陪伴了我整个青春</strong>”的评论通知邮件时，我突然觉得，<strong>这一切都值了</strong>。这种<strong>得到他人肯定，且确实帮助到他人</strong>的感觉，太棒了。</p>
<p>想起最初的<strong>「互联网精神」：开放、平等、协作、分享</strong>。如今许多科技公司都在打造自己的封闭生态圈，进行“垄断”，商业变现的路上“吃相”愈发难看，不由得为之唏嘘。而<strong>大多数个人博客</strong>，不以盈利为目的，默默进行着<strong>信息与资源的传播共享</strong>，可能这就是纯粹的技术吧。</p>
<p>如果你也曾在无人知晓的角落默默努力，请相信，<strong>时间会为每一位坚持者，准备最甜的彩蛋。</strong></p>
<p>每个人都有独属于自己的「十年故事」。在你的十年故事里，是否也有一个<strong>无人问津，却仍坚持至今的「喃小柯站」</strong>？</p>
<p><img decoding="async" src="https://img.manshaoco.com/i/2025/05/01/6813838561c55.webp" alt="2025年3月的博客截图" title="%title插图%num" /></p>
<p>这十年里，尽管我已成长了很多，但许多问题，诸如「<strong>奋斗的意义</strong>」、「<strong>人为何而活</strong>」，我仍然给不出一个令我感到满意的答案。</p>
<p>但，<strong>人生的这份试卷仍在继续</strong>，我们仍在行进，在不断书写属于自己的那份或许并不完美，但一定是独一无二的答案。</p>
<p>我曾以为的<strong>「参考答案」</strong>，实际上是：<strong>略</strong>。</p>
<p>下一个十年，愿我们依然，<strong>对技术保持敬畏，对未知渴求探索</strong></p>
<p>就像那个十一岁用上网本，第一次编译构建 Visual Basic 程序的少年：</p>
<p><strong>Stay hungry, stay foolish.</strong></p>
<p>共勉。</p>
<hr />
<h4>附录</h4>
<ol>
<li>
<p>感谢这十年来<strong>所有帮助过我的见过或未曾见面的人</strong>，尤其是我的家人、朋友们。</p>
</li>
<li>
<p>文中这十年的网站截图，来自“网页时光机”<strong>Wayback Machine</strong>，如果你也有自己的网站，或许可以在<a href="https://web.archive.org/" title="这里">这里</a>找到曾经的网页快照。但时光机不会记录复杂的 css 和 js，所以可能会出现像第二张图样式丢失的情况，问题不大。</p>
</li>
<li>
<p>「<strong>Stay hungry, stay foolish</strong>」摘自 <strong>Steve Jobs</strong> 于 2005 年在斯坦福大学毕业典礼上的发言，关于这句话的含义可以参考<a href="https://www.ruanyifeng.com/blog/2015/05/stay_hungry_stay_foolish.html">这篇文章</a>，我比较认同以下这篇回答：<br />
<img decoding="async" src="https://img.manshaoco.com/i/2025/05/02/6814c4ac299c6.webp" alt="知乎上的对于stayHungryStayFoolish的回答" title="知乎上的对于stayHungryStayFoolish的回答" /></p>
</li>
<li>
<p>「<strong>参考答案：略</strong>」的灵感来自同名歌曲（<strong>好听，快去听</strong>）：<br />
<img decoding="async" src="https://img.manshaoco.com/i/2025/05/02/6814b8e0c3817.webp" alt="歌曲-参考答案：略" title="歌曲-参考答案：略" /></p>
</li>
<li>
<p><strong>DeepSeek-R1</strong> 是这篇文章的第一位读者，咱的博客也是有读者了，555</p>
<p><img decoding="async" src="https://img.manshaoco.com/i/2025/05/02/6814c4eab8b71.webp" alt="DeepSeek评价" title="DeepSeek评价" /></p>
</li>
<li>
<p>非常感谢你能看到这里，<strong>祝你生活愉快</strong>！</p>
</li>
</ol>
]]></content:encoded>
					
					<wfw:commentRss>https://www.manshaoco.com/1361.html/feed</wfw:commentRss>
			<slash:comments>16</slash:comments>
		
		
			</item>
		<item>
		<title>爬取全民K歌指定用户的全部歌曲</title>
		<link>https://www.manshaoco.com/1354.html</link>
					<comments>https://www.manshaoco.com/1354.html#respond</comments>
		
		<dc:creator><![CDATA[Fotink]]></dc:creator>
		<pubDate>Thu, 22 Aug 2024 14:12:58 +0000</pubDate>
				<category><![CDATA[工具]]></category>
		<guid isPermaLink="false">https://www.manshaoco.com/?p=1354</guid>

					<description><![CDATA[最近突然想把以前在全民K歌录的所有歌曲都存下来，因此就想找找网上有没有合适的爬虫代码。翻了一圈，Github  [&#8230;]]]></description>
										<content:encoded><![CDATA[<div id="core-ai-summary-tool"></div><p>最近突然想把以前在全民K歌录的所有歌曲都存下来，因此就想找找网上有没有合适的爬虫代码。翻了一圈，Github 上的几个项目都是五六年前的了，有些年代感了；CSDN 和知乎上的两位大佬分享的代码，如今也都没办法正确执行了。<br />
但好在 CSDN 和知乎的两位大佬写了比较详细的思路和代码编写过程，结合咱也略懂一点点爬虫知识，所以花了几个小时，在前人的基础上，咱改出了一个可用的爬虫方案。<br />
受时间所限，代码写的比较草率，GET请求具体携带的参数咱也没完全弄清楚，所以就不提交到 GitHub 了，哈哈。<br />
需要的朋友直接拿去使用就行。感谢两位原作者：<a href="https://blog.csdn.net/user_from_future/article/details/120924995" title="user_from_future">user_from_future</a>、<a href="https://zhuanlan.zhihu.com/p/522224991" title="陶陶name">陶陶name</a></p>
<pre><code class="prettyprint"  class="language-python">import os,re
import json
import requests
from bs4 import BeautifulSoup

# 解析 Cookies
def parse_cookies(cookies: str):
    cookies_dict = {}
    for c in cookies.replace(&#039; &#039;, &#039;&#039;).split(&#039;;&#039;):
        try:
            cookies_dict[c.split(&#039;=&#039;)[0]] = c.split(&#039;=&#039;)[1]
        except IndexError:
            cookies_dict[c.split(&#039;=&#039;)[0]] = &#039;&#039;
    if &quot;&quot; in cookies_dict:
        del cookies_dict[&quot;&quot;]
    return cookies_dict

# 处理标题
def cleanUGCListTitle(ugclist):
    def clean_filename(filename):
        # 定义非法字符
        illegal_chars = r&#039;[\\/:*?&quot;&lt;&gt;|\r\n]+&#039;
        # 匹配 &quot;
        illegal_chars += r&#039;|&quot;&#039;
        illegal_chars += r&#039;|&amp;#39;&#039;
        # 替换非法字符
        cleaned_filename = re.sub(illegal_chars, &#039;&#039;, filename)
        return cleaned_filename

    for item in ugclist:
        item[&#039;title&#039;] = clean_filename(item[&#039;title&#039;])
    return ugclist

# 获取用户基本信息
cookie = input(&#039;请输入有效的 Cookie（XHR中选一）：&#039;)
header = {&quot;Cookie&quot;: cookie, 
          &quot;User-Agent&quot;: &quot;Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1&quot;,
          &quot;Referer&quot;: &quot;https://static-play.kg.qq.com/&quot;}
uid = parse_cookies(cookie)[&#039;muid&#039;]
print(f&#039;\n获取到 Cookie 中的用户 UID：{uid}&#039;)
inp = input(&#039;请输入需要查询的 UID，否则获取用户自身：&#039;)
if len(inp) &gt; 10:
    uid = inp
totalCount = 0  # 可以获取到的歌曲总数
songList = []  # 全部歌曲列表
user_information = {}  # 用户基本信息
res = requests.get(f&#039;https://kg.qq.com/node/personal?uid={uid}&#039;, cookies={&quot;cookie&quot;: cookie})

# 遍历获取所有单曲信息
if res.ok:
    for script in BeautifulSoup(res.text, &#039;lxml&#039;).find_all(&#039;script&#039;):
        if &quot;window.__DATA__&quot; in script.text:
            user_information = json.loads(script.text[script.text.find(&#039;{&#039;): script.text.rfind(&#039;};&#039;) + 1])[&quot;data&quot;]
            # 没有cookies == 公开的歌曲 | 有cookies == 账户所有的歌曲 || 能够被获取到的歌曲数目
            totalCount = user_information[&quot;ugc_total_count&quot;]
            print(f&#039;当前用户总歌曲数：{totalCount}&#039;)
            if not os.path.exists(f&#039;{user_information[&quot;kgnick&quot;]}/media&#039;):
                os.makedirs(f&#039;{user_information[&quot;kgnick&quot;]}/media&#039;)
            num = 15  # 单次获取最大15首
            n = 1  # 页数
            while n:
                url = f&#039;https://node.kg.qq.com/fcgi-bin/kg_ugc_get_homepage?&#039;
                params = {
                    &quot;outCharset&quot;: &quot;utf-8&quot;,
                    &quot;from&quot;: &quot;1&quot;,
                    &quot;nocache&quot;: &quot;1724248787425&quot;, # 不知道是个啥参数，从kg_ugc_get_homepage里面解析出来的
                    &quot;format&quot;: &quot;json&quot;,
                    &quot;type&quot;: &quot;get_uinfo&quot;,
                    &quot;start&quot;: n,
                    &quot;num&quot;: num,
                    &quot;share_uid&quot;: uid,
                    &quot;g_tk&quot;: &quot;5381&quot;,
                    &quot;g_tk_openkey&quot;: &quot;1970486037&quot; # 同样不知道是个啥参数，可能和身份鉴别有关，也是从kg_ugc_get_homepage里面解析出来的
                }
                res = requests.get(url, params=params, headers = header)
                if res.ok:
                    try:
                        start_brace_index = res.text.find(&#039;{&#039;)
                        end_brace_index = res.text.rfind(&#039;}&#039;)
                        if start_brace_index != -1 and end_brace_index != -1:
                            song_information = json.loads(res.text[start_brace_index:end_brace_index + 1])[&quot;data&quot;]
                            print(song_information)
                            if not song_information[&quot;ugclist&quot;]:
                                break
                            # 处理一下 ugclist 中的非法标题，并加入所有歌曲列表中
                            songList += cleanUGCListTitle(song_information[&quot;ugclist&quot;])
                            n += 1
                        else:
                            print(&quot;响应文本中找不到有效的 JSON 格式&quot;)
                    except json.JSONDecodeError as e:
                        print(f&quot;JSON 解析错误: {e}&quot;)
                        # break
            break
    else:
        print(&#039;未发现歌曲！&#039;)

# 遍历保存单曲文件
if user_information:
    open(f&#039;{user_information[&quot;kgnick&quot;]}/{user_information[&quot;kgnick&quot;]}_{uid}.json&#039;, &#039;w&#039;, encoding=&#039;utf-8&#039;).write(json.dumps(songList, indent=4, ensure_ascii=False))
    for i, song in enumerate(songList):
        res = requests.get(f&#039;https://node.kg.qq.com/play?s={song[&quot;shareid&quot;]}&#039;, cookies={&quot;cookie&quot;: cookie})
        if res.ok:
            for script in BeautifulSoup(res.text, &#039;lxml&#039;).find_all(&#039;script&#039;):
                if &quot;window.__DATA__&quot; in script.text:
                    media_information = json.loads(script.text[script.text.find(&#039;{&#039;): script.text.rfind(&#039;};&#039;) + 1])[&quot;detail&quot;]
                    if media_information[&quot;playurl_video&quot;] != &#039;&#039;:
                        play_url = media_information[&quot;playurl_video&quot;]
                        file_extension = &quot;.mp4&quot;
                    elif media_information[&quot;playurl&quot;] != &#039;&#039;:
                        play_url = media_information[&quot;playurl&quot;]
                        file_extension = &quot;.m4a&quot;
                    else:
                        print(&#039;当前歌曲下载失败，可能是全民K歌的歌曲文件获取规则已变化，请修改爬虫代码！&#039;)
                        break

                    res = requests.get(play_url, stream=True)
                    if res.ok:
                        print(f&#039;\r正在下载：{user_information[&quot;kgnick&quot;]}/media/{song[&quot;title&quot;]}_{song[&quot;shareid&quot;]}{file_extension}\n【当前：{str(i + 1).zfill(len(str(totalCount)))}/总共：{totalCount}】&#039;, end=&#039;&#039;)
                        open(f&#039;{user_information[&quot;kgnick&quot;]}/media/{song[&quot;title&quot;]}_{song[&quot;shareid&quot;]}{file_extension}&#039;, &#039;wb&#039;).write(res.content)
                    break
            else:
                print(&#039;未发现媒体链接！&#039;)
    print()

input(&#039;下载完成！回车结束程序~&#039;)</code></pre>
<p>大部分代码其实就是 <strong>user_from_future</strong> 大佬的方案，只不过我精简掉了 <strong>自动获取 Cookie、下载专辑</strong> 的功能，毕竟咱只是想保存自己的全部歌曲嘛，这些功能就用不上了。<br />
相比于 <strong>user_from_future</strong> 的源代码，这里我首先完善了全部歌曲的获取方式。说白了还是他所提到的“查看更多”那个 <strong>kg_ugc_get_homepage</strong> 的 GET 请求，只不过如今全民K歌那边，加了<strong>禁止空 referer 的限制</strong><br />
这个问题困扰了我一晚上，哈哈哈，还好咱建网站十年了，略懂这些，最后还是把这个小问题排查出来了。实测对这个请求，随便携带一个 referer 都能获取成功，这里保险起见，咱还是携带了它自己的域名。<br />
同时，PC 端全民个人主页只能显示出 8 首歌曲，但如果用开发者选项改成移动端 UA，就能无限拉出全部歌曲了。每下拉一次，都会发出一次 GET 请求（kg_ugc_get_homepage）<br />
<img decoding="async" src="https://img.manshaoco.com/i/2024/08/22/66c7423d75925.webp" alt="全民K歌 XHR请求" title="全民K歌 XHR请求" /><br />
这个请求的返回结果里，就有每次请求返回的 10 首歌。只不过我没有弄清楚请求携带的 nocache 以及 g_tk_openkey 的意义，所以这里就直接按照我自己的结果写了。<strong>如果不能用，你可以将代码中的这部分内容，修改为你的请求中的对应参数</strong>。<br />
同时注意，这个请求是可以返回<strong>设为私密歌曲的结果</strong>的，前提是你得使用自己的 Cookie 去获取自己的歌曲。否则只能返回其他人公开的歌曲。<br />
同时，我注意到有些作品是视频形式的，它的视频文件 URL 与音频文件的 URL 所在的键值对不太一样，因此在代码中我区分了二者，使其能够保存所有的全民K歌作品。鉴于 Windows 的命名规范，代码中也加入了标题规范化的功能，但仅仅只是将非法字符去掉，会导致部分歌曲的命名很奇怪。如有更好的做法，可以分享出来，谢谢。</p>
<hr />
<p><strong>Cookie 的获取方法</strong>：用电脑登录 kg.qq.com，然后点击右上角的扫码登录，使用 App 完成扫码登录后，点击顶部的“个人中心”，然后 F12 进入浏览器开发者选项，切换“网络”Tab，接着点一下网页底部的“更多歌曲请前往 App 查看”，这时开发者选项中就多出了一个 <strong>kg_ugc_get_homepage</strong> 的请求结果，将它的 Cookie 完整复制出来就行了（务必要完整复制出来）<br />
使用上述 Python 爬虫脚本前，请确保你的电脑上安装了 <strong>requests、beautifulsoup4、lxml</strong> 这三个库，如果没有安装，请先使用<code class="prettyprint" >pip install {库名}</code>来安装</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.manshaoco.com/1354.html/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>人生很长，值得做你想做的事情</title>
		<link>https://www.manshaoco.com/1347.html</link>
					<comments>https://www.manshaoco.com/1347.html#respond</comments>
		
		<dc:creator><![CDATA[Fotink]]></dc:creator>
		<pubDate>Thu, 08 Aug 2024 14:03:55 +0000</pubDate>
				<category><![CDATA[随笔]]></category>
		<guid isPermaLink="false">https://www.manshaoco.com/?p=1347</guid>

					<description><![CDATA[&#8195;&#8195;今天是2024年8月8日，距离北京奥运会开幕，过去了整整十六年。回想起十六年前的这个时 [&#8230;]]]></description>
										<content:encoded><![CDATA[<div id="core-ai-summary-tool"></div><p>&emsp;&emsp;今天是2024年8月8日，距离北京奥运会开幕，过去了整整十六年。回想起十六年前的这个时候，很多事情逐渐涌上了心头。所以想着在这里写一些碎碎念，记录一下此时的想法和那些记忆中的事情。</p>
<hr />
<p>&emsp;&emsp;十六年前，印象中的大事件有两件：汶川地震和北京奥运会。那会儿我才6岁，5月12日发地震那会儿，我已经没啥印象了，根据后来推测，那会儿可能在幼儿园睡午觉。据爸妈说，那会儿他俩在室内和室外，都感觉到了震感。<br />
&emsp;&emsp;地震对那时的我来说，最大的感触就是，那段时间，回家之后打开电视，所有的频道都在转播地震的新闻，没有动画片看了。每天看到地震新闻，刚开始还会觉得有些压抑和恐惧，到后面只希望，死亡人数不要再增加了，希望地震和救灾工作早点结束，愿所有人都能好好的 [/比心]<br />
&emsp;&emsp;除此之外，那段时间恰逢幼儿园六一文艺汇演的排练和素材录制时期。还记得小时候搬家，我换过好多次幼儿园，2007年时，我所在的那所幼儿园请了摄影师，全程录制了六一汇演，此后每个小朋友都交钱换来了一张录像的光盘。搬家后，我在母亲的建议下，向幼儿园老师张老师提出了录制光盘的建议，她很高兴地采纳了。此后我和其他小朋友，便很认真地准备着我们的节目。<br />
&emsp;&emsp;其中之一，就是《北京欢迎你》的演唱。还记得当时分给我的歌词是“北京欢迎你，为你开天辟地，流动中的魅力充满着朝气”；后来，似乎是因为地震，我们安排了一个舞蹈节目《相亲相爱一家人》</p>
<hr />
<p>&emsp;&emsp;六一汇演结束，便进入了幼升小的暑假。这个暑假里，舅舅邀请我们几位小朋友去他家，和表姐一块儿玩了一段时间。<br />
&emsp;&emsp;那段时间里，我们去的最多的地方，就是“销品茂”购物中心。印象中的销品茂，很高，很大，应该也确实是武汉当时最大的商场了。我们几个小朋友就在里面玩捉迷藏。玩累了，还有免费的瓶装汽水可以喝。<br />
&emsp;&emsp;后来我再也没去过销品茂了，16年了，一直以为它已经倒闭了，直到在网上查了下，才发现它前两年居然还闭店翻修了。从居住附近的朋友那里得知，销品茂后来改名中商世界了，修的还挺好看。后面有机会倒是准备再去故地重游一下，哈哈。<br />
&emsp;&emsp;2008年8月8日晚上8点，北京奥运会在这样一个很吉利的时刻开幕。原本那天舅舅计划带着我们一群小朋友，去附近的一块儿很大的荧幕前，观看奥运会开幕式直播。结果表弟那天上午发烧腹泻，舅舅和舅妈带着表弟去看病了，折腾一天，晚上也就待在家里没出门了。</p>
<hr />
<p>&emsp;&emsp;印象中那天的开幕式直播，我没有看成，毕竟是小朋友嘛，和其他小朋友在一块儿，就想着玩儿，所以那会儿可能就去玩儿了，也就没管奥运会这些。直至十年后，我才完整看完刘欢和 Sarah Brightman 合唱的那首《我和你》的 MV；2021年，东京奥运会开幕式结束后，我才完整看了一遍北京奥运会的开幕式[/捂脸]，内心感触很深。<br />
&emsp;&emsp;想来也是，小时候那会儿看了开幕式，可能也只会觉得，是一场盛大的汇演。<strong>只有当有了一定的人生阅历后，再去看北京奥运会的开幕式，内心的那种家国情怀才会被触动</strong>。此后，随着对当年奥运会幕后的那些筹备的了解，才逐渐意识到那一年的奥运会，全国上下究竟付出了怎样的努力和心血，打造出了这样一场，如今回顾仍能让人热泪盈眶的视觉和听觉的盛宴！<br />
&emsp;&emsp;小时候对奥运会感触最深的，应该是后来上小学三年级的时候，在买过的《意林》合订本的一篇连载小说。具体的名字不记得了，可能是“一个人的星球”，讲述的是一位劫后存生于某个星球的宇航员的故事。伴随着他的，只有一个记录着《我和你》的机器人。小说描写的那个场景，让我感触很深刻。那一瞬间，我才意识到，奥运会的这首歌，<strong>体现了大国开放的胸怀，一种情怀</strong>。</p>
<blockquote>
<p><strong>You and me,<br />
From one world.<br />
We are family.<br />
Travel dream,<br />
A thousand miles.<br />
Meeting in Beijing.<br />
来吧，朋友<br />
伸出你的手<br />
我和你，心连心<br />
永远一家人</strong></p>
</blockquote>
<p>&emsp;&emsp;<strong>再次听到这首歌，眼眶有些湿润</strong>。<br />
&emsp;&emsp;后来，假期结束，升学进入小学。六年后，进入初中；三年后，进入高中；四年后，进入大学。十六年里，一个个时间节点，标志着不同阶段的自己，踏上了一段段新的旅程。<br />
&emsp;&emsp;十六年，对于当时只有六岁的我来说，似乎很长很长，遥不可及。那时的我还没有考试的烦恼，每天幼儿园放学，写完作业就能坐在电视机前看《喜羊羊与灰太狼》、《猪猪侠》、《果宝特攻》这些动画片。那时的我，对所有新事物都感到好奇。老爹的新手机、家里的新彩电我都要琢磨个透。<br />
&emsp;&emsp;<strong>十六年后的我，变了，但没完全变</strong>。在家人眼里，我从原来的活泼开朗，变得不爱说话。而我知道，我还是，从前那个内心善良，对所有新鲜事物保持好奇的少年。<br />
&emsp;&emsp;无论怎样，<strong>好好活下去吧，去做些自己想做的事</strong>，我们的人生还有好几个十六年呢！如果这些事儿中，<strong>能有一些为他人，为我们的国家提供价值的</strong>，那可就太棒辣！</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.manshaoco.com/1347.html/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Gitea 数据迁移（数据库变更指南）</title>
		<link>https://www.manshaoco.com/1322.html</link>
					<comments>https://www.manshaoco.com/1322.html#comments</comments>
		
		<dc:creator><![CDATA[Fotink]]></dc:creator>
		<pubDate>Sat, 20 Apr 2024 02:30:57 +0000</pubDate>
				<category><![CDATA[实践]]></category>
		<guid isPermaLink="false">https://www.manshaoco.com/?p=1322</guid>

					<description><![CDATA[最近进行了网站服务器的整理优化后，才发现之前安装 Gitea 时埋了一个坑。 因为那时我的 MySQL 没有  [&#8230;]]]></description>
										<content:encoded><![CDATA[<div id="core-ai-summary-tool"></div><p>最近进行了网站服务器的整理优化后，才发现之前<strong>安装 Gitea 时埋了一个坑</strong>。<br />
因为那时我的 MySQL 没有 Docker 化，<strong>容器内的 Gitea 无法通过内网连接宿主机器的 MySQL</strong>，所以在安装配置 Gitea 时，我选择了 SQLite3 数据库。<br />
而如今为了便于统一管理，我还是决定将 Gitea 的 SQLite3 迁移至 MySQL，原本以为只是简单的数据库信息迁移，没想到折腾了<strong>八个小时</strong>才解决，因此记录下踩过的坑，和最终的解决方案。</p>
<h2>使用 SQLite3 命令行</h2>
<p>刚开始搜索“<strong>SQLite 转 MySQL</strong>”时，文心一言给出的方案是，使用 <code class="prettyprint" >sqlite3 original.db .dump &gt; result.sql</code> 这一终端操作。<br />
我半信半疑地试了下，发现在我的 Windows 11 机器上面，确实有 <code class="prettyprint" >sqlite3</code> 这么个命令行工具，并且这个命令确实能生成 <code>.sql</code> 文件。<strong>但我尝试将其导入到 MySQL 时，它从第一行内容就开始报错……</strong><br />
去搜索了之后才得知，<strong>前几行的内容是 SQLite 特有的指令</strong>，也难怪 MySQL 会报错。但我将其删除后，仍旧无法导入。<br />
使用 <strong>phpMyAdmin</strong> 手动添加数据后，进行命令比对才发现，<code class="prettyprint" >.sql</code> 执行的语句的格式还是与我的导出格式存在差异（比如所有的数字都会以字符串的形式输入，<del>不知道是不是这个原因导致报错</del>）</p>
<h2>使用第三方软件</h2>
<p>网上很多人的方案是使用 <strong>Navicat</strong> 进行 <strong>SQLite → MySQL</strong> 的转换。<br />
首先我去搜了下，需要使用的版本是 <strong>Navicat Premium</strong>，而这是一个商业软件。因此这种方案颇有一种<strong>为了一碗醋包了一碟饺子</strong>的感觉…<br />
但解决需求要紧，通过一些<strong>开心的手段</strong>最终是用上了这个软件。<br />
网上有两种方法：</p>
<ol>
<li>直接在表中将所有数据进行导出</li>
<li>使用菜单栏的“工具”→“数据传输”</li>
</ol>
<p>这两种方法我都试过，<strong>方法一</strong>存在<strong>语法规范问题</strong>（比如表名会加上双引号，数字不会以字符串形式输入），且会将每一个表单独导出为一个 <code class="prettyprint" >.sql</code> 文件，咱还得合并或者多次导入；而<strong>方法二</strong>导出的 <code>.sql</code> 文件虽然已经很接近 <strong>phpMyAdmin</strong> 导出的 <code>.sql</code> 文件了，但在导入时仍旧会报错。<br />
我也尝试在使用<strong>方法一</strong>时，将其导出为 <code class="prettyprint" >.csv</code> 文件，但仍旧在导入时出现问题……</p>
<h2>使用在线工具</h2>
<p>毕竟咱要操作的是数据库，把数据库丢到云端处理，<strong>多少还是有些不放心</strong>，但最后实在是没办法了，所以我尝试使用 <a href="https://www.rebasedata.com/" title="RebaseData">RebaseData</a> 的转换服务，并且为了导出完整数据，还注册了一个账号…<br />
最终结果，<strong>既有好消息也有坏消息</strong>，好消息是，该在线工具确实可以将 Gitea 的 SQLite3 数据库文件转为 MySQL 的 <code class="prettyprint" >.sql</code> 文件，且能正常导入到 MySQL；坏消息是，导入之后我的 Gitea 直接 <strong>502</strong> 了……<br />
尝试了很多次，排查了各种其他问题后，最终确定仍旧是数据库没有正确转换。</p>
<h2>最终解决方案</h2>
<p>在 Google 上使用英文关键词找到了有效的解决方案<br />
<a href="https://github.com/go-gitea/gitea/issues/26862"><a href="https://github.com/go-gitea/gitea/issues/26862"><a href="https://github.com/go-gitea/gitea/issues/26862">https://github.com/go-gitea/gitea/issues/26862</a></a></a><br />
原来 Gitea 是有<strong>命令行工具</strong>的，而该命令行工具支持生成<strong>转储文件</strong>，且能指定生成的转储文件中的<strong>数据库导出格式</strong>。<br />
所以最后按照 <a href="https://docs.gitea.com/next/administration/command-line#dump" title="Gitea 官方教程">Gitea 官方教程</a> 使用 <code class="prettyprint" >gitea dump --database mysql</code> 即可获得包括可导入的 <code>.sql</code> 文件在内的转储文件压缩包。<br />
只不过在 Docker 内，卷的映射和写入权限<strong>有一丢丢麻烦</strong>。这里我是修改了 Gitea 的容器，重新映射了一个新的 <code class="prettyprint" >\backups</code> 文件夹到容器内，然后在该文件夹内执行上述命令，即可得到最终的转储文件压缩包。<br />
至于<strong>该如何在 Docker 内执行终端命令</strong>的话……我的面板的容器管理界面是可以进入该容器的终端的，所以直接<strong>以非 root 身份登录 Gitea 容器的终端</strong>即可（比如我的 Gitea 是以 <code class="prettyprint" >git</code> 账户运行的）</p>
<h2>总结</h2>
<p>除了上述尝试过的方案，其实还有其他理论可行的方案，例如<strong>编写 Python 脚本</strong>，实现一对一地将 SQLite3 的数据库条目写入到 MySQL 数据库中。但出于<strong>时间成本</strong>和<strong>生产环境</strong>的考虑，我没有尝试该方法。而且<strong>不排除 Gitea 对 SQLite3 和 MySQL 的数据存储方式有区别</strong>，可能仍会出错。有兴趣的小伙伴可以试试。<br />
其实最初<strong>文心一言</strong>也给过我 <code class="prettyprint" >使用 Gitea 终端工具</code> 的类似方案，但那时我没有看到它的这一结果的信息来源，以为是某些不可靠的信息拼凑出来的结果。现在想想，AI 工具还是挺有前途的~</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.manshaoco.com/1322.html/feed</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title>在 OpenWrt 配置 Cloudflare DDNS</title>
		<link>https://www.manshaoco.com/1309.html</link>
					<comments>https://www.manshaoco.com/1309.html#comments</comments>
		
		<dc:creator><![CDATA[Fotink]]></dc:creator>
		<pubDate>Mon, 26 Feb 2024 10:15:33 +0000</pubDate>
				<category><![CDATA[教程]]></category>
		<guid isPermaLink="false">https://www.manshaoco.com/?p=1309</guid>

					<description><![CDATA[写在开始 前几天给 NAS 换了基于 Docker 的 CasaOS，想着装一个frpc 以备不时之需，结果在 [&#8230;]]]></description>
										<content:encoded><![CDATA[<div id="core-ai-summary-tool"></div><h2>写在开始</h2>
<p>前几天给 NAS 换了基于 Docker 的 CasaOS，想着装一个frpc 以备不时之需，结果在应用商店看到了 Cloudflared（cloudflare/cloudflared），原来 Cloudflare 也有提供类似 frp 的 Tunnel 服务，而且目前是有免费计划可以使用的。<br />
<strong>这个 Tunnel 比 frp 配置起来更简单</strong>，客户端只需要开好对应的 Docker 后运行，并输入由 Cloudflare 生成的 Token，就不需要再操作了。剩下的端口映射以及域名绑定都是在 Cloudflare 网页操作。<br />
但是，<strong>若想绑定自己的域名，就必须先将整个域名添加到 Cloudflare</strong>，想了想也挺合理的，都免费提供穿透服务了，附带着给自己的产品增下用户量也没啥问题。<br />
<strong>只不过，这样就得把我对应域名的域名服务器（NS）修改过去了。</strong>此前这个域名用 DNSPod 的时候我在路由器上配置过 DDNS，折腾了很久。这次换了 Cloudflare 之后，没想到又折腾了半天，网上没有找到完整的教程，因此在这里记录一下折腾的心得和踩过的一些坑。</p>
<h2>参数配置</h2>
<p><img decoding="async" src="https://img.manshaoco.com/i/2024/02/26/65dc5a0753491.webp" alt="Cloudflare-DDNS-OpenWrt配置" title="Cloudflare-DDNS-OpenWrt配置" /><br />
<strong>查询主机名</strong>直接填自己解析的域名就行；<br />
<strong>域名</strong>这里必须得用“@”分隔自己的主域名和子域的名字（Cloudflare奇奇怪怪的规则）；<br />
<strong>用户名</strong>填写自己 Cloudflare 账号的邮箱；<br />
<strong>密码</strong>填写自己 Cloudflare 账号的 Global API Key（点右上角头像→个人资料→ API 令牌）</p>
<p>此外，为确保稳妥，还需要进入<strong>高级设置</strong>，修改获取 IP 地址的方法<br />
<img decoding="async" src="https://img.manshaoco.com/i/2024/02/26/65dc5baed38c9.webp" alt="修改获取IP地址的方法" title="修改获取IP地址的方法" /><br />
按照图上的设置，修改为通过 URL 获取 IP 地址，然后填写下方的例子即可</p>
<h2>折腾心得</h2>
<p>OpenWrt 我已使用一个多月，可以说它能够实现所有需要的功能，只不过网上现成的教程和参考比较少，很多功能需要自己不断尝试才能实现，有时也需要一些 Linux 基本功。<br />
在配置 DDNS 时，luci-app-ddns 提供的这些服务商接口的用法各不相同，就比如它提供的这个 Cloudflare 与我在网上找到的一篇文章所使用的 DDNS 接口就不一样。<strong>遇到这种问题时，最有效的方法就是查看日志</strong>（编辑自己添加的 DDNS 服务→日志查看器→读取/重新读取日志文件），可以在这里查看接口是否和自己配置的是同一接口。如果接口配置是正确的，但仍报错，也可查看具体是何种错误（luci-app-ddns 主页就只会显示一个 XHR Error -_-）。<br />
如果中文搜索引擎无法搜寻到有帮助的信息，可以试试用 Google 或者 Bing 搜索英文关键词，有时也能找到国外论坛的有用的帖子。</p>
<h2>参考文章</h2>
<p><a href="https://blog.csdn.net/qq_40961831/article/details/108799784" title="python3利用cloudflare api批量解析域名及配置page rules">python3利用cloudflare api批量解析域名及配置page rules</a></p>
<p><a href="https://www.nixonli.com/3.html" title="CloudFlare DDNS OpenWrt 配置的一些坑">CloudFlare DDNS OpenWrt 配置的一些坑</a></p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.manshaoco.com/1309.html/feed</wfw:commentRss>
			<slash:comments>6</slash:comments>
		
		
			</item>
		<item>
		<title>构建自己的 OpenWrt 路由固件</title>
		<link>https://www.manshaoco.com/1298.html</link>
					<comments>https://www.manshaoco.com/1298.html#respond</comments>
		
		<dc:creator><![CDATA[Fotink]]></dc:creator>
		<pubDate>Sat, 10 Feb 2024 16:51:43 +0000</pubDate>
				<category><![CDATA[实践]]></category>
		<guid isPermaLink="false">https://www.manshaoco.com/?p=1298</guid>

					<description><![CDATA[最近给宿舍和家里都换了中国移动的 RAX3000M 路由器，更换的原因是，手头的手机、电脑、平板都支持 Wi- [&#8230;]]]></description>
										<content:encoded><![CDATA[<div id="core-ai-summary-tool"></div><p>最近给宿舍和家里都换了中国移动的 RAX3000M 路由器，更换的原因是，手头的手机、电脑、平板都支持 Wi-Fi 6 了，而我的旧路由还是 Wi-Fi 5 的；同时，最近热门的这款 RAX3000M 既支持 Wi-Fi 6，还有一个少见的 USB 接口（我正好需要通过手机共享网络给路由器），最重要的是，它的价格只需要百来块，所以我前后给宿舍和家中都更换了这款路由器。</p>
<h2>开始刷机</h2>
<p>到手后，原厂的中国移动的固件比较简陋，而且据说对网络也存在限制，因此我迅速按照大佬们的教程，开启 SSH 并进行刷机（更换固件）<br />
操作方法可以参考<a href="https://www.right.com.cn/forum/thread-8316001-1-1.html" title="这篇帖子">这篇帖子</a>，核心就是解压缩配置文件，删除 root 用户密码以及开启 SSH，只不过较新版本的这款路由的配置文件加了密码，因此需要使用下面两条命令解压缩和重新打包</p>
<pre><code class="prettyprint"  class="language-bash">// 解压缩
openssl aes-256-cbc -d -pbkdf2 -k $CmDc#RaX30O0M@\!$ -in cfg_export_config_file.conf -out - | tar -zxvf -
// 重新打包
tar -zcvf - etc | openssl aes-256-cbc -pbkdf2 -k $CmDc#RaX30O0M@\!$ -out cfg_export_config_file_new.conf</code></pre>
<h2>选择固件</h2>
<p>刷入 uboot 之后就需要刷入新的固件了，这里我首先用了恩山<a href="https://www.right.com.cn/forum/thread-8315980-1-1.html" title="这位坛友">这位坛友</a>定制的固件，顺利刷入之后就能通过 192.168.100.1 以及 passwd 进入后台了。<br />
此前我没有使用过原生 OpenWrt 以及 ImmortalWrt，所以刚开始为了设置 Wi-Fi 以及连接手机共享网络，折腾了很久，好在这个固件还是能够满足我的这些需求。<br />
只不过这个固件的版本号里面带有坛友的 QQ 号，想象一下，每次进入路由器后台，第一眼看到的是别人的 QQ 号，多少有点煞风景，因此我准备<strong>定制自己的固件</strong>。</p>
<h2>定制固件</h2>
<p>了解一番之后才知道，原来<strong>现在已经有 openwrt.ai 这样的在线自助构建固件的工具网站了</strong>，只不过该网站在未捐助的情况下能够选择的插件数比较少，且会加上一行该构建网站的广告按钮。<br />
我尝试构建并刷入后，说实话，这个工具网站提供的功能已经非常丰富了，而且上面那位恩山坛友构建的固件的来源也是这里，只不过他是捐助用户，因此可以自定义版本号等细节信息。<strong>如果没有特别多的插件需求，其实用这个定制自己的 OpenWrt 固件足够了</strong>。<br />
<img decoding="async" src="https://img.manshaoco.com/i/2024/02/11/65c79de42fba2.webp" alt="OpenWrt.ai 在线构建固件网站" title="OpenWrt.ai 在线构建固件网站" /><br />
当然，<strong>除了该定制固件的方法外，还有相对传统一点的，使用 ImageBuilder 构建自己的固件的方法</strong>，详细可参考 <a href="https://openwrt.org/zh/docs/guide-user/additional-software/imagebuilder" title="官方教程">官方教程</a>。<br />
我是在恩山找教程的时候找到了某位坛友分享的教程，他将内容保存为了 html 网页进行分享，<strong>这里实在不好意思，我找不到原帖子了</strong>，只能将他的 <a href="https://www.123pan.com/s/nFn9-wpoD3.html" title="源文件">源文件</a>(提取码1234) 贴上来，供大家参考。<br />
文章中有些地方没有说明白，比如<strong>需要首先下载需要的源外插件到 packages 目录中</strong>，这里<strong>可以配合上述的 OpenWrt.ai 中的插件中文名，以选择自己需要的插件</strong>并保存至 packages 目录。<br />
除此之外，配置文件我没有用上，所以在最后的那条最长的构建固件的命令中，不需要加最后的“FILES='files'”部分。<br />
构建完成后，即可在“bin/targets/mediatek/filogic/”目录下获得两个 .bin 后缀的文件，这就是我们需要的固件了，刷入即可。</p>
<h2>使用心得</h2>
<p>1、<strong>使用 OpenWrt.ai 构建的固件能够正常设置 160MHz 的 Wi-Fi</strong>，说人话就是，在支持的设备上，连上 Wi-Fi 可以看到协商的最高速度能达到 2400Mbps；<strong>而使用上述 ImageBuilder 构建的固件仅能正常使用 80MHz</strong>，协商速度最高为 1200Mbps.</p>
<p>2、网络设置项都在“接口”项目中，默认应该是支持 DHCP 的，如果需要使用拨号上网或者 USB 共享网络，可以直接新建一个新的接口，选择 PPPoE 或者 usb0，防火墙规则选择 wan，不开启 DHCP，保存并应用即可生效。</p>
<p>3、如果你有公网 IPv6 地址，可尝试使用 DDNS 做 IP 解析，然后修改防火墙设置开放端口。（话说回来我还没研究明白，等啥时候折腾好了再单独写一篇文章吧）</p>
<p>4、如果你没有公网 IP，可以安装 frpc 插件进行内网穿透。luci-app-frpc 可以替代几乎所有 frp 服务网站自己的客户端，因为他们的客户端也基本都是魔改的。所以推荐你在创建好 frp 隧道后，直接寻找隧道的配置文件信息，然后对着 luci-app-frpc的设置项进行填写即可。只不过，需要注意，下图框出的这个“服务备注名”必须按照 frp 服务网站的配置文件中的隧道备注名（由“[xxx]”标注，那么填写xxx），否则你的隧道无法连上。<br />
<img decoding="async" src="https://img.manshaoco.com/i/2024/02/11/65c7a79972c04.webp" alt="frpc 重要设置项目" title="frpc 重要设置项目" /></p>
<h2>写在最后</h2>
<p>OpenWrt 是一个好东西，我仍记得第一次了解到它，是在小米路由 MiWiFi 上见到的—— MiWiFi 是基于 OpenWrt 深度定制的 ROM. 也确实，之前在用小米路由的时候，虽然偶尔会有一些小 bug，但 MiWiFi 仍然是一个<strong>简洁、易用</strong>的好固件。<br />
所以，如果你有一颗愿意折腾的心，不妨试试这个可以高度自定义的固件。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.manshaoco.com/1298.html/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>湖北创维 HC2910 安装第三方 App / 替换桌面</title>
		<link>https://www.manshaoco.com/1300.html</link>
					<comments>https://www.manshaoco.com/1300.html#comments</comments>
		
		<dc:creator><![CDATA[Fotink]]></dc:creator>
		<pubDate>Sat, 10 Feb 2024 15:53:12 +0000</pubDate>
				<category><![CDATA[教程]]></category>
		<guid isPermaLink="false">https://www.manshaoco.com/?p=1300</guid>

					<description><![CDATA[大概五六年前，家里的广电有线电视机顶盒进行了一次升级，换成了类似三大通信运营商 IPTV 的方案。几年前家中已 [&#8230;]]]></description>
										<content:encoded><![CDATA[<div id="core-ai-summary-tool"></div><p>大概五六年前，家里的广电有线电视机顶盒进行了一次升级，换成了类似三大通信运营商 IPTV 的方案。几年前家中已经不再续费电视套餐，这套盒子也就闲置吃灰许久，直至最近过年才想起。在网上搜索了一下相关教程，结合自己实际操作情况，整理了一份安装 App 和替换桌面的教程。</p>
<h2>工具准备</h2>
<p>1、创维 HC2910 盒子<br />
2、电视机<br />
3、电脑<br />
4、U 盘</p>
<h2>开启 ADB 服务</h2>
<p><strong>首先安装“悟空遥控广电版”至盒子</strong>。下载 <a href="https://www.123pan.com/s/nFn9-ZxoD3.html?提取码:2333" title="该 APK">该 APK</a> 放置于 U 盘中，然后插入盒子右侧的 USB 接口。<br />
使用遥控器切换至主页最右侧“我的”，选择“本地播放”，然后选择“sda1”，点开我们的悟空遥控 apk 进行安装（该 apk 在允许安装的白名单内）并打开。<br />
<strong>接着安装手机版悟空遥控</strong>。这里随便去百度找一个能用的版本就行，因为官网已经停服了。也<a href="https://www.123pan.com/s/nFn9-exoD3.html?提取码:2333" title="备份一下">备份一下</a>我正在使用的版本。<br />
在手机版悟空遥控连接到盒子后，使用“工具箱”左上角的“电视设置”即可<strong>打开盒子的原生 Android 设置</strong>。<br />
<img decoding="async" src="https://img.manshaoco.com/i/2024/02/10/65c73da6098d8.webp" alt="悟空遥控器打开机顶盒设置" title="悟空遥控器打开机顶盒设置" /><br />
直接划到最底部的“开发者选项”，可以看到“USB 调试”已经默认勾选，<strong>这里我们先将其勾掉，然后重新勾选即可真正打开 USB 调试</strong>。</p>
<h2>安装第三方 App</h2>
<p>完成上述操作后，此时 HC2910 机顶盒实际上已经开启了 ADB 网络调试功能（尽管 Android 4.4 并无 无线调试 功能，但这款海思方案的机顶盒似乎是魔改了系统使其支持该功能）。<br />
在电脑上准备好需要安装的第三方 App，然后使用 ADB 复制到用户应用目录(/data/app)或者系统应用目录(/system/app)即可。<br />
<strong>只是，需要注意，这款盒子的系统是 Android 4.4，如今依然支持安装的 App 数量很少，所以部分软件可能需要寻找标注了支持 4.4 的版本或老版本</strong>。<br />
在电脑上使用 ADB 建议首先配置环境变量，也可直接在 SDK Platform Tools 的目录中执行命令，可参考 <a href="https://www.manshaoco.com/871.html" title="先前的文章">先前的文章</a> 下载该工具包<br />
准备好 ADB 后，依次执行</p>
<pre><code class="prettyprint"  class="language-bash"># 首先通过悟空遥控查看设备 IP 地址
adb connect 192.168.1.108       # 连接机顶盒，需要修改自己盒子设备的 IP 地址
adb push C:\Users\Fotink\TVBox.apk /data/app/TVBox.apk      # 将本地安装包推送至用户应用目录
# 如果需要推送至系统应用目录，则需要首先执行
adb root
adb remount     # 重新挂载使 system 目录可读写
# 然后再推送安装包
adb push C:\Users\Fotink\TVBox.apk /system/app/TVBox.apk</code></pre>
<p>至于为啥不用 adb install 是因为我安装不上……不会解除这个设备安装应用的白名单限制</p>
<h2>替换原有桌面（启动器）</h2>
<p>替换的原因是因为，如果只是额外装一个启动器，就算将其设置为默认桌面，每次启动后还是会弹选择启动器的提示。<br />
因此一不做二不休，正好这个盒子的 ADB 有 ROOT 权限，咱们可以随意修改 /system/app 下的内容，只不过有些东西还是谨慎修改为好，修改前请务必做好分区备份，万一寄了还有个恢复的办法。<br />
我首先尝试更换为“当贝桌面”，但不知为何 3.3.6 以及最新的 4.x 版本都在这台盒子上闪退，因此我在酷安找到了一位老哥 <a href="https://www.coolapk.com/feed/22621284" title="修改过的启动器">修改过的启动器</a>，装上之后很好使，你可以 <a href="https://xkys.lanzoux.com/iybzxhxu03i" title="点击这里">点击这里</a> 下载<br />
下载之后，请直接改名为 Launcher.apk，然后在电脑执行下列操作</p>
<pre><code class="prettyprint"  class="language-bash">adb connect 192.168.1.1     # 连接到盒子
adb shell       # 进入该设备的 ADB 终端
su      # 确保已经切换至 ROOT 用户
adb remount     # 重新挂载 system 目录
mv /system/app/Launcher.apk /system/Launcher.apk        # 将原本的桌面移出去而不是删除，万一以后需要恢复了捏
exit        # 退出 ADB Shell
adb push C:\Usesrs\Fotink\Launcher.apk /system/app/Launcher.apk     # 将咱们的新桌面传过去</code></pre>
<p>ok，这样操作之后，重启盒子应该就能进入咱们的第三方桌面了。<strong>你问接下来怎么进入传统电视模式？</strong>在咱们的桌面上添加一个“湖北直播IPTV”的快捷方式即可，进入这个 App 就是传统的电视模式。</p>
<h2>一些想法</h2>
<p>这部盒子比较特殊，头一次见打开 ADB 就能切换到 ROOT 权限的 Android 设备，也因此，<strong>我们可以执行上述所提到的这些“直接复制到安装目录”而非常规安装的操作</strong>。不过在折腾过程中，我也遇到了一些问题。</p>
<p>1、可以安装在 Android 4.4 的应用太难找了；<br />
2、很多应用通过上述手段安装后无法正常打开，猜测可能需要手动设置下文件权限；<br />
3、仍然没有找到解除安装白名单的方法。我尝试安装 MT 管理器以替代自带的包管理器，但 1.0 的版本都无法在这部盒子上正常运行；<br />
4、家中的这部盒子还是 2020 年的开机广告，每次开机都要等 1-2 分钟，没能找到妥善处理开机广告的方法。</p>
<p>如果有使用相同设备的朋友能解决这几个问题，欢迎在下方留言交流。<br />
最后，写完这篇文章的时候，已经是大年初一的晚上了，在这里，<strong>我祝各位在接下来的日子里都能顺风顺水，学业有成，事业顺心，身体健康，阖家欢乐！</strong></p>
<h2>小彩蛋</h2>
<p>如果你关注过我之前的文章，可能会注意到我在这篇文章中对“安卓”的英文使用，从“android”变更为了“Android”，这是因为 Google 官方在前不久进行了这样的措辞变更。<br />
此外，文中所有 123 网盘 的链接，提取码均为 <strong>2333</strong> ，其实提取码就在链接中，只不过编码导致了中文乱码，所以你可能没有看出来~</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.manshaoco.com/1300.html/feed</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>macOS 抹除后无法通过互联网恢复的解决思路</title>
		<link>https://www.manshaoco.com/1294.html</link>
					<comments>https://www.manshaoco.com/1294.html#comments</comments>
		
		<dc:creator><![CDATA[Fotink]]></dc:creator>
		<pubDate>Tue, 16 Jan 2024 10:59:08 +0000</pubDate>
				<category><![CDATA[实践]]></category>
		<guid isPermaLink="false">https://www.manshaoco.com/?p=1294</guid>

					<description><![CDATA[一块儿做项目的同学手头有台闲置的 MacBook，型号是 2019 款的 Pro，前些天他将这台电脑出给了当地 [&#8230;]]]></description>
										<content:encoded><![CDATA[<div id="core-ai-summary-tool"></div><p>一块儿做项目的同学手头有台闲置的 MacBook，型号是 2019 款的 Pro，前些天他将这台电脑出给了当地的一位买家。但在抹除后，他<strong>无法通过互联网恢复功能下载 RecoveryOS 和 macOS</strong>，致使电脑无法正常使用。</p>
<h2>折腾过程</h2>
<p>拿到后，开机就会自动进入互联网恢复模式，初步判断当前硬盘没有任何系统。推测 macOS 的抹除功能其实与手动格盘重装系统无异（怪离谱的，至少留个 RecoveryOS 方便装系统嘛）。<br />
在连接 Wi-Fi 后，电脑开始下载格盘前原系统版本对应的 RecoveryOS，但尝试了两次均失败，一次是<strong>报错 -2003F</strong>，还有一次忘记了。我尝试搜索该错误，未能找到有帮助的信息，通过苹果官网的文档，推测是当前网络环境连接苹果的下载服务器不稳定导致的。<br />
第三次重新连接 Wi-Fi 下载后，终于成功进入了 RecoveryOS，看来确实是网络不稳定导致的。<br />
进入 RecoveryOS 后，系统会自动联网激活电脑（可能是联网检测当前电脑是否处于丢失模式或者是否有 ID?），问题来了，加载了一会儿之后，屏幕显示“<strong>无互联网连接</strong>”，考虑到这台电脑目前连接的是同学的电信网络的热点，可能电信网络连接苹果服务器暂时不太稳定，因此我更换了自己的联通网络的热点，重新尝试激活后成功，总算是可以安装系统了。</p>
<p>但还没高兴两个小时，重新安装 macOS Ventura 终止在了结尾部分，电脑提示“<strong>需要互联网连接才能安装 macOS</strong>”，然而这个时候电脑一直连接着手机热点，不可能没联网。<br />
尝试了两次均失败后，<strong>我决定通过 U 盘的方式安装 macOS</strong>，但将写好的 U 盘插入电脑后，电脑要么是网络问题，无法通过 Option 进入系统切换菜单，要么就是好不容易能到切换系统的界面了，但回车后无法进入 U 盘引导的安装界面。<br />
此后了解到，2019 款的 MacBook 配有 Apple T2 安全芯片，电脑安全性设置限制了通过 U 盘启动。而如果需要更改该设置，必须在启动时按住 Option 键后，再按 Command + R 进入RecoveryOS 找到安全性设置再进行关闭。也就是说，<strong>直接进入 RecoveryOS 是无法更改安全性设置的</strong>。</p>
<p>按照上面的组合键，我成功进入了这台电脑出厂版本系统（也就是 Catalina）的 RecoveryOS，但是，当我点进“安全性设置”后，系统让我输入管理员密码，<strong>但这台电脑抹除后，连系统都没有了，哪里来的管理员账户呢？</strong>因此，更改安全性设置陷入了死循环，通过 U 盘安装系统的操作无法进行。</p>
<p>到这里看起来似乎没有办法解决了，但同学在抖音寻找解决办法时，发现<strong>苹果有一种名为 DFU 的刷机模式</strong>，只不过为了给这台 MacBook 通过这种方式刷机，还需要一台能够正常使用的 MacBook，并且可能需要使用 Thunderbolt 接口的线材。</p>
<p>最后，考虑到，<strong>如果确实是服务器连接不稳定的问题，似乎可以通过科学上网来解决</strong>。因此回宿舍掏出了路由器，设置好了全局代理，然后重新安装 macOS，在经过了三小时的漫长等待后，系统终于装好啦。</p>
<h2>原因与解决方案</h2>
<p><strong>原因</strong>：部分运营商与苹果的下载分发服务器的连接不稳定。<br />
<strong>解决方法</strong>：更换不同运营商的网络，或者尝试给这台电脑挂全局代理服务器下载。</p>
<h2>写在最后</h2>
<p>苹果的这个抹除机制确实还不够完善，后续有待改进。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.manshaoco.com/1294.html/feed</wfw:commentRss>
			<slash:comments>4</slash:comments>
		
		
			</item>
		<item>
		<title>macOS 提示“您没有权限来打开应用程序”的解决方法</title>
		<link>https://www.manshaoco.com/1285.html</link>
					<comments>https://www.manshaoco.com/1285.html#respond</comments>
		
		<dc:creator><![CDATA[Fotink]]></dc:creator>
		<pubDate>Wed, 15 Nov 2023 08:24:21 +0000</pubDate>
				<category><![CDATA[教程]]></category>
		<guid isPermaLink="false">https://www.manshaoco.com/?p=1285</guid>

					<description><![CDATA[起因 最近安装某软件时，头一次遇到 macOS 提示“您没有权限来打开应用程序 请联系您的电脑或网络管理员以获 [&#8230;]]]></description>
										<content:encoded><![CDATA[<div id="core-ai-summary-tool"></div><h2>起因</h2>
<p>最近安装某软件时，头一次遇到 macOS 提示“您没有权限来打开应用程序 请联系您的电脑或网络管理员以获得帮助”。<br />
<img decoding="async" src="https://img.manshaoco.com/i/2023/11/15/1700035014.webp" alt="macOS 无权限提示" title="macOS 无权限提示" /><br />
试过了以往的那些打开未知来源 App 的解决方法，均无法解决。最后好不容易找到了一篇文章，看完那篇文章后，大致明白了造成这一问题的原因，于是很快解决了。</p>
<h2>解决方法</h2>
<p>1、先检查一下可执行文件的状态：对着应用包右键“显示包内容”→“Contents”→“MacOS”，这个目录下应该存在一个和应用同名的可执行文件。通常，这个文件的图标应该是一个<strong>黑色的“exec”</strong>，其种类为“<strong>Unix可执行文件</strong>”。但此时却变成了<strong>白色图标</strong>，“<strong>文稿</strong>”类型。<br />
<img decoding="async" src="https://img.manshaoco.com/i/2023/11/15/1700035341.webp" alt="检查可执行文件状态" title="检查可执行文件状态" /><br />
也就是说，这个文件在该软件发布的过程中，<strong>因为各种原因丢失了其可执行的属性，也就导致整个软件没有了可执行权限</strong>。所以我们要做的，就是给它<strong>重新赋予可执行的权限</strong>。<br />
2、打开终端，输入“<strong>chmod +x</strong>”，然后敲一个空格，再将上述文件拖入终端，按回车后即可为该文件赋予可执行权限。<br />
<img decoding="async" src="https://img.manshaoco.com/i/2023/11/15/1700035969.webp" alt="赋予可执行权限" title="赋予可执行权限" /><br />
3、回到访达，可以看到该文件的<strong>图标已经变黑</strong>，种类变为了<strong>可执行文件</strong>。<br />
<img decoding="async" src="https://img.manshaoco.com/i/2023/11/15/1700036037.webp" alt="赋予可执行权限后的文件" title="赋予可执行权限后的文件" /><br />
4、重新打开该软件，一切正常。</p>
<h2>写在结尾</h2>
<p>在我找到的<a href="https://www.mac8k.com/h-nd-196.html" title="那篇文章">那篇文章</a>中，解决方法是，安装一个 pkg 包，然后使用命令行执行该 pkg 包，为上述可执行文件执行一次操作。<br />
虽然不太清楚具体的原理，但我猜测与直接使用 chmod 命令为其赋予可执行权限的效果一致。<br />
秉持着“<strong>能不装未知软件就不装</strong>”的想法，我撰写了这篇教程，希望能够帮到其他遇到这一问题的朋友。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.manshaoco.com/1285.html/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
