自己动手去除车玻璃油膜

油膜是车玻璃上的顽固污垢,会影响视线,用玻璃水和雨刷(雨刮器)无法清除。油膜折磨我很久了,下雨天开雨刷,就是在均匀涂抹油膜,非常影响视线。终于自己动手解决了,很有成就感,嘻嘻😁。 车玻璃去油膜需要氧化铈清洁剂,大概步骤如下: 开车到自助洗车店(需要用高压水枪)。 打开雨刷检修模式,自行抬起雨刷。 喷水清洗玻璃,去除沙尘。 将氧化铈清洁剂1(玻璃抛光剂)滴到玻璃上,用羊毛毡海绵均匀转圈揉搓整面挡风玻璃,如果擦不干净就稍微加大力度擦。这个方法的原理就是通过轻微抛光把玻璃表面的油膜擦掉。 喷水清洗玻璃上的清洁剂。 观察玻璃,确认清洗干净。如果仍不干净,可再滴清洁剂重复擦拭,然后喷水冲洗。 用湿抹布擦干净残留的清洁剂。 喷水清洗玻璃。 放下雨刷。 如果用雨刷之后又模糊,就是雨刷胶条脏了,换掉雨刷胶条即可。 用氧化铈毕竟是打磨玻璃,建议清洁过后平时多清洁玻璃,避免油膜。 下面是我的清洁记录。 一开始用氧化铈清洁剂擦了三四轮挡风玻璃,玻璃干净了。用布擦了雨刷胶条,胶条还是能擦出黑色的污渍。喷玻璃水后用雨刷,玻璃又模糊了。上网买了雨刷胶条(雨刮片/雨刷片),自己换上后用雨刷也不脏了。 我还买了防冻米其林玻璃水,它号称去污去除虫胶鸟粪。轩逸经典引擎支撑架居然在引擎上,怪不得我一开始找了很久没找到,看手册找到玻璃水仓。加玻璃水一定要看手册确认位置,注意不要倒去机油仓或者冷却液仓。大概花了 2 分钟喷完车里的玻璃水,倒了 2.4 升玻璃水也没倒满。以后打算开车前都喷玻璃水清洁玻璃,希望没那么快有油膜。 极旅汽车玻璃油膜抛光剂(150 ML 清洁剂(成分:去离子水、氧化铈、分散剂NNO)、羊毛毡海绵、毛巾)约 17 元人民币,万孚雨刮片约 22.5 元,米其林玻璃水约 19 元,洗车约 15 元,共计 73.5 元。 用氧化铈去油膜的方法是我在粉丝惨遭二手车商套路,40天找不到车?告诉你怎么把黑车贩子干到破产! - 百车全说这期节目听到的,感谢主播三刀。自己洗车|除油膜最靠谱的方法是。。。_哔哩哔哩_bilibili这个视频讲得也不错,可以参考。 氧化铈粉末比调配好的清洁剂便宜,但是有意外吸入的风险。我建议买调配好的清洁剂和配套工具,额外戴手套和口罩操作。 ↩︎

2026/1/5
articleCard.readMore

PRORASO 桉树薄荷剃须皂使用体验

PRORASO 桉树薄荷剃须皂(绿色包装)是一款经典的剃须皂,平时价格 50 元人民币左右,我发现天猫自营有 33.95 元的就买了。 这款皂装在碗里,质地不硬,可以轻松用勺子挖出来。打泡沫有一点点难,没有 Arko 皂棒那么简单。打泡沫时少量多次加水,试多几次就会了。打好泡沫之后,把泡沫摸到手指再洗掉,手指会变得防滑。 这款皂清凉舒爽,可提神和舒缓伤口。热天用很爽,冷天用有点凉。泡沫容易洗掉,不会像 Arko 那样让脸变干。 已经用 2 个月了,还没用完,体验不错,没发现它有什么明显的缺点。

2025/12/14
articleCard.readMore

我不用或少用的剃须装备和护肤品

本文列举了我不用或少用的剃须装备和护肤品,供对剃须和护肤感兴趣的读者参考。 请注意,每个人肤质、胡须和需求不同,这里列举的产品只是不适合我,不一定就是坏产品。 关于我目前用的剃须装备和护肤品,请看这篇文章。 # 剃须润滑产品: 罐装剃须泡沫(刺激皮肤,不如剃须皂耐用) 剃须啫喱(黏糊糊,沾到剃须刀上难清洁,在脸上也不容易洗掉,不如剃须皂耐用) Arko 皂棒(会让皮肤变干,洗脸后仍有部分残留在脸上) 起泡碗: 宠物慢食碗 350 毫升款(起泡碗,凸起太高,剃须皂残留在碗底,浪费剃须皂,打泡沫时阻力大) 剃须刀: 大多数盒式剃须刀(不耐用,贵,多达 5 层的刀片会更快刮掉保护皮肤的角质层) 舒适水次元 5 智能调压敏感肌(Schick Hydro Sensitive Skin Razor) 吉列云感(Gillette SkinGuard) 吉列锋隐至顺(Gillette ProGlide) 吉列极光(GilletteLabs with Exfoliating Bar) 犀牛牌剃须刀(塑料材质太轻,剃须时需要自己额外加压力,操作难度大) 百利 179D(我买的第一把双刃剃须刀,难操作,刮完皮肤火辣辣的。它差点让我弃用双刃剃须刀,坏的开始是失败的一半) 顺便说个冷知识,其实犀牛牌剃须刀是吉列的产品。 # 大宝水凝保湿精华水 150ML(刺激皮肤) 百雀羚维生素 E 精华乳(用了后皮肤有点紧绷)

2025/12/13
articleCard.readMore

我用的剃须装备和护肤品

本文列举了我目前使用的剃须装备和护肤品,供对剃须和护肤感兴趣的读者参考。 请注意,每个人肤质不同,这里列举的产品可能不适合你。 我懒得写价钱,感兴趣的读者可以留言让我补充。 关于我不用或少用的剃须装备和护肤品,请看这篇文章。 # 旁氏米粹洁面乳 旁氏米粹洁面泡泡 # 剃须皂和配套工具: PRORASO 桉树薄荷剃须皂(绿色包装) 10 厘米不锈钢勺子(用于挖剃须皂) FRUIT SONG 芦荟凝胶(加一些到剃须泡沫,泡沫会绵密水润) 剃须刷: 2 个 YAQI 盲盒瑕疵剃须刷(第 2 只本来打算送给朋友,但是拿到手太喜欢就自己用了,哈哈) 支架: 2 个 YAQI 瑕疵剃须支架(可以同时放剃须刷和剃须刀,我一般只放剃须刷) 起泡碗(内面有突起的碗更容易打泡沫,不过光滑的碗也是可以的): 日式浮雕陶瓷碗 剃须刀和配套工具: 同诗 S9 电动剃须刀 穆乐 Muhle R89 闭合式双刃剃须刀 RazoRock OLD TYPE(UFO 手柄)开放式双刃剃须刀(RazoRock 的手柄防滑且沉重,非常好用,我用其他剃须刀也喜欢接这个手柄) 超级蓝吉列(SUPER Gillette BLUE)闭合式双刃剃须刀 帝诗便携安全剃须刀包 舒适超巧(Schick Exacta 2) 双刃刀片和配套产品(建议先买刀片体验套装,不同刀片的使用感受不一样,遇到合适的再多买): Astra Superior Platinum(俗称绿A) Bic Chrome Platinum(俗称黄比克) Derby Premium(俗称黑德比) Feather Hi-Stainless(俗称黄羽毛) Feather New Hi-Stainless(俗称黑羽毛) Perma-Sharp(俗称黄脸、马杀鸡1) 软木塞(用刀片划软木塞,可以消除刀刃的毛刺) 骰子(放在刀片旁标记使用次数) # 止血: ISOOQI 60 克明矾棒(涂了皮肤会干,所以只有出血的时候用) 须后水 / 爽肤水: 吾诺 UNO 爽肤水 200 ML(带柑橘味和一点酒精味) 保湿: 大宝 SOD 清爽保湿凝露(蓝瓶,热天用) 大宝 SOD 蜜(红瓶,冷天用) 曼秀雷敦润唇膏 SPF 15 # ANESSA 防晒霜 60ML 搞不懂为什么 Perma-Sharp 被称为马杀鸡。这种让人摸不著头脑的黑话只会增加新手学习门槛。 ↩︎

2025/12/13
articleCard.readMore

将一加 Ace 3 从 LineageOS 22.2 升级到 23.0

昨天才装好 LineageOS 22.2,今天就推出 23.0 了。这时 LineageOS 大版本升级保留数据的优势就体现出来了。 虽然大版本升级会保留数据,但还是用 DataBackup 备份数据和应用,以防不测。将备份文件复制到 U 盘。 按照升级教程来升级系统。 1 2 3 4 5 6 adb -d reboot sideload adb -d sideload lineage-23.0-20251012-nightly-aston-signed.zip # 重启至 recovery,安装谷歌套件(之前安装过,升级的时候也要安装新版本) adb -d sideload MindTheGapps-16.0.0-arm64-20250812_214353.zip # 安装 KernelSU Next 内核 adb -d sideload ksu-next.zip 搞定,重启到系统,一切正常,删除 U 盘的备份。

2025/10/12
articleCard.readMore

给一加 Ace 3 安装 LineageOS 22.2

2025 年 10 月 12 日更新:LineageOS 已经更新到 23 版了,建议安装 23 版。安装了 22.2 版还得升级到 23 版本。 PixelOS 15 三四个月没更新,我发现 LineageOS 22.2 已经支持一加 Ace 3,所以打算安装 LineageOS。我更喜欢 LineageOS,因为它每周更新,还支持大版本更新。 # 备份微信 1 到电脑 备份微信 2 到电脑 截图记录闹钟 截图记录 Outlook 账号 截图记录谷歌账号 截图记录星标联系人 截图记录 root 模块 用 DataBackup 备份(需要 root 权限) DCIM Download Documents Pictures 应用(显示一个应用出错,不是微信就行) 测试删除应用后是否可以恢复 将备份复制到电脑(显示需要一个半小时,USB 2.0 好慢,复制还会报错) 将备份复制到 U 盘(备份 50G,可以放到 64G 的 U 盘) # 退出谷歌账号,以免手机安装系统后被锁定。 # 先看完安装教程,要求手机使用 Android 15 固件。我的一加 Ace 3 之前用 ColorOS 15.0.0.500 系统,后来又安装了 15.0.0.820 固件,符合安装要求。 以下是安装流程记录(你安装的时候应该看教程,不要抄我的步骤): 1 2 3 4 5 6 fastboot flash boot boot.img fastboot flash dtbo dtbo.img fastboot flash init_boot init_boot.img fastboot flash vbmeta vbmeta.img fastboot flash vendor_boot vendor_boot.img fastboot flash recovery recovery.img 在手机用音量键选择 Recovery mode,按电源键确认。 清除数据:Factory Reset -> Format data / factory reset 安装系统:Apply Update -> Apply from ADB 1 adb -d sideload lineage-22.2-20251010-nightly-aston-signed.zip 电脑显示 47% 进度,手机已经安装完系统了,询问是否重启到 recovery,选择 Yes。 安装谷歌套件:Apply Update -> Apply from ADB 1 adb -d sideload MindTheGapps-15.0.0-arm64-20250812_214357.zip 手机显示 Signature verification failed(签名认证失败),选择 Yes,继续安装。 选择 Reboot system now,进入系统。 # 恢复备份需要 root 权限,试一下我之前没用过的 KernelSU Next。 内核在 https://github.com/inferno0230/kernel_oneplus_sm8550-CI/releases 下载。这次我用的是 https://github.com/inferno0230/kernel_oneplus_sm8550-CI/releases/download/LineageOS_OPSM8550-v5.15.189-20251008/ksu-next.zip。 管理器在 https://github.com/KernelSU-Next/KernelSU-Next/releases 下载,这次我用的是 https://github.com/KernelSU-Next/KernelSU-Next/releases/download/v1.1.1/KernelSU_Next_v1.1.1-spoofed_12851-release.apk。 在手机开启开发者模式,开启 USB debugging,连接电脑,同意 USB debugging。 安装管理器: 1 adb install KernelSU_Next_v1.1.1-spoofed_12851-release.apk 按住电源下键,重启手机到 fastboot,再进入 recovery。 安装内核:Apply Update -> Apply from ADB 1 adb -d sideload ksu-next.zip 手机显示 Signature verification failed(签名认证失败),选择 Yes,继续安装。 选择 Reboot system now,进入系统。 打开 KernelSU Next,显示 working(运作中)。 安装 Re-Malwack 和 universal-gms-doze。 # 复制备份到手机 恢复数据 恢复应用(高德地图恢复失败,其他没事) # 删除 U 盘的应用和数据备份 删除电脑的微信聊天记录备份 # 登录 Bitwarden 登录 Outlook 开启联系人同步 登录谷歌账号 登录支付宝。居然可以用指纹支付了,惊喜!微信和云闪付还是无法开启指纹支付。 锁屏时关闭敏感通知 设置星标联系人 设置闹钟 安装 althafvly/ih8sn(用 recovery 安装了 2024-11-16 发布的版本)。安装后无法启动系统,我就卸载掉了。安装ItsVixano/ih8sn,系统能开机,但是不能通过 Play Integrity 和 SafetyNet,所以还是卸载掉了。目前 Play Integrity 检测结果是都不通过。 # PixelOS 的特色功能: 人脸识别解锁 通过 Play Integrity 的前两项 LineageOS 的特色功能: 通话录音(需要手动按)

2025/10/11
articleCard.readMore

别过度手动剃须

最近两三天,我每天手动剃须一到两次。无论是用我很熟悉的舒适超巧还是新买的百利 179D,脸部皮肤都有刺痛感和灼烧感(razor burn),涂明矾后刺激感尤其明显。之前用舒适超巧没出现这样的问题。 通过一段时间的实验,我发现问题的原因是手动剃须频率太高。将剃须频率降低到两三天一次后就没事了。 用手动剃须刀时,刮掉的不仅仅是胡子,还有皮肤最外面的角质层。频繁剃须让角质层被刮得比生长得快,进而导致皮肤受伤。 两三天才刮一次胡子,那胡子长出来怎么办?当然是用不会刮掉角质层的电动剃须刀。顺便说一句,电动剃须刀也得清洗和换刀头。刀片切过胡子,一定会越来越钝,太钝的刀片会扯胡子。不清洗剃须刀,剃须刀里面会滋生细菌,臭烘烘的,这些细菌甚至会感染皮肤,让皮肤又红又痒。

2025/10/8
articleCard.readMore

同诗 S9 便携剃须刀使用体验

平时我用手动剃须刀,剃须少说也要十分钟,还要配套工具。有时候没时间或者不方便用手动剃须刀,所以我打算买一把便携剃须刀备用。我希望这把剃须刀在用着舒适的情况下,尽量剃得干净。 我买的同诗 S9 价格是 367.2 元人民币。一组刀头价格是 49 元,替换成本不算高,花费可能比盒式剃须刀还便宜。同诗 S9 使用后还可以无理由退货(建议购买前向客服确认),好评! 选择同诗 S9 主要是看中它转速高(单个刀头每分钟最高 5000 转)、外观好看、小巧便携、USB Type-C 充电。这里批评一下商品页面写得 10000 rpm 转速,看起来很快,但这个转速简直是误导消费者,这 10000 rpm 是两个刀头的转速相加。转速根本就不能加起来,一个刀头它最高速度就是 5000 rpm。举个例子,两个人并排跑步,速度都是 10 km/h,你不能说他们速度加起来是 20 km/h,一起跑步又不会变快。 我买的颜色是冰河银。外观确实不错,表面看起来是金属,拿着重量也是金属,但是摸起来却是光滑的感觉。表面摸多了就有点黏糊糊的。我还以为贴了膜,刮半天发现并没有膜。有收纳袋,但是没有刀头保护盖。 正面写着 PUNK(朋克)和 CHAOKU SHAVER(超酷剃须刀)。你的外观已经够酷了,不用说出来,好吗? 同诗 S9 用 3 种颜色表示 3 个档位。什么颜色对应什么档位呢?看说明书闭上眼睛仔细地听吧。 听,海哭刀片的声音~叹息着谁又被伤了心~ 蓝色是 1 档,最低速。青色是 2 档。绿色是 3 档。长按开关会启动旅行锁,此时按开关不会启动剃须刀,长按开关即可解锁旅行锁。 从档位显示这里就可以看出这是一把极简的剃须刀,所以电量显示肯定没有,只有低电量的时候才闪灯提醒。同诗 S9 电量不足时会扯胡子,所以最好提前充电,避免电量不足,它闪灯就不要用了。 同诗 S9 剃须舒适,有盒式剃须刀七八成的效果,不会让脸看着邋遢。刀网压在皮肤上可以剃得更干净,但是这样会痛。刮下巴底下的胡子有时候会痛。 最近用盒式剃须刀刮上唇附近的胡子时不时刮伤,我就用同诗 S9 比较多。因为电动剃须刀有刀网保护皮肤,所以不会刮伤。即使电动剃须刀剃得不是很干净,也可以多剃几次。盒式剃须刀的刀片直接接触皮肤,刮多了容易把皮肤磨掉。 同诗 S9 是便携式剃须刀,可以轻松放进裤袋。出行的时候带它,确实比带盒式剃须刀省事多了。盒式剃须刀配套的装备比较多,有洗面奶、剃须皂、剃须刷、明矾、面霜。 说明书没写拆卸刀头的方法,要问客服要视频。要用牙签挑出来,后续安装有点麻烦。同诗 S9 的刀头是磁吸的,方便拿下来。我剃了胡子之后就取下刀头,抓着刀头,把底部往洗手盆拍,把胡渣拍出来。我每天睡前取下刀头后用水冲洗刀头和传动轴,再放着晾干。第二天早上刀头和机身都干了,可以继续用了。按照这个清洗方法,用了一段时间,刀头不臭。 这把剃须刀可以湿剃,我试过搭配剃须啫喱或者剃须皂,都是没有干剃那么顺。尤其是剃须皂,用了之后刀头在皮肤移动时有阻力。 评价后送电动鼻毛修剪器,Type-C 充电,机身小巧,全身可水洗。我用了 1 次,效果不错,但鼻子痒痒的,会打喷嚏。 用同诗 S9 两个多星期了,剃须效果有点超出预期,满意。写完这段话没多久,有个刀头有异响,于是换货了。换货后用了 10 天,没问题。 最后给厂商一些建议:加上档位和电量显示灯、把表面做成清爽的、把刀头设计成容易拆卸的。

2025/9/30
articleCard.readMore

Arko 剃须皂棒使用体验

2025-12-13 更新:Arko 会让皮肤变干,而且洗脸后还是有部分残留在脸上。PRORASO 桉树薄荷剃须皂就没有这些缺点。 买了 Arko 75g 皂棒 + 便携瓶子,21.8 元人民币。我还买了 YAQI 盲盒刷子(25 元),350 毫升宠物慢食碗(10.8 元,用来打泡沫)。 剃须皂棒的用法: 冲洗碗 冲一下皂棒 把皂棒按到碗里,旋转几下,留一些皂在碗里 用刷子放到碗里旋转,顺时针旋转和逆时针旋转,很快出泡沫 用刷子把泡沫抹到脸上,用刷子在脸上旋转 剃须 再次剃须前重新往脸抹泡沫 这是我第一次用剃须皂,就和剃须啫喱对比一下吧。 Arko 剃须皂防刮伤的效果比花王 Success 剃须啫喱(粉色保湿型、金色多刀片型)好很多,现在刮上唇和鼻子之间的胡子没那么容易受伤。 用刷子抹泡沫非常方便,刮同一个地方前随时可以抹泡沫。用啫喱就比较麻烦,按出来涂了脸还得洗手(啫喱很滑)。 剃须皂打出来的泡沫一冲就走,剃须啫喱则会粘在刀头上,水压不够冲不掉就得用牙刷配合,边刷边冲。 Arko 皂棒的味道是老式肥皂的味道,我挺喜欢这种香味。Arko 皂棒的味道大,最好晾干后密封装到瓶子里,不然整个房间都是肥皂味。 用了 Arko 皂棒之后脸有点干,要涂面霜保湿。Arko 皂棒被我扭断捏扁后放到京都念慈庵薄荷糖的圆盒(60 克)了,这个盒子正好可以放下皂棒。如果你也打算将皂棒放到圆盒,建议把整个皂棒扭成圆球再压进去,不要想我一样扭断皂棒。 已经用了两三个星期 Arko 皂,感觉没用多少,真是便宜耐用。

2025/9/29
articleCard.readMore

ISOOQI 明矾棒使用体验

2025-10-28 更新: 皮肤科医生告诉我:剃须后没有明显不适的话,不需要用须后产品(比如明矾),剃须后皮肤有细微刮伤不要紧,皮肤会在三至五天内自行恢复。 明矾的副作用是让皮肤变干变紧绷,所以用了明矾要额外涂面霜补水。我建议只有明显出血或者刮伤才涂明矾,不要每次都涂明矾,以免皮肤失水。靓仔,你也不想让你帅气的脸庞变得干巴巴的,对吧。先失水再补水简直是在折磨皮肤啊。 在淘宝买了 ISOOQI 明矾棒,60 克,有盖子,14.39 元人民币。商家说是 100% 钾明矾。 明矾在剃须的主要作用是止血消炎。剃须后把明矾涂到脸上,痛表示刮伤了,不痛表示没刮伤。手指沾水后摸一下明矾,可以让手指变得防滑。 刚打开明矾棒的时候凑过去问,明矾和盖子内部有股臭味。用了一次之后把明矾和盖子放桌子上,过了一天就不臭了。 用水冲一下明矾棒,剃胡子后抹脸上,有伤口就会刺痛(明矾是一种盐,体会到伤口上撒盐的感觉了)。流血了抹几下也很快止血。 十多二十秒后洗掉脸上的明矾,皮肤有点紧绷。 明矾棒太小了,涂很多次才能涂满脸。更大面积的明矾块应该会比较好用。 有可以拧紧的盖子,方便外出携带。 明矾是物美价廉的剃须装备,推荐购买。明矾就像救护车,平时不一定会用,但是有它在就更安心。 这款明矾棒底部会积水,盖上盖子闷着容易长疙瘩,用了不擦干也会起疙瘩。如果用力甩干水,明矾棒底部会松动,容易从底座掉落。 2025-10-11 更新:拿到 40 天后,明矾棒已经从底座脱落,表面还有不少疙瘩。

2025/9/29
articleCard.readMore

舒适超巧:也许是盒式剃须刀的终点

一把舒适牌的剃须刀,内含 2 层美国产刀片,你猜猜多少钱? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 分 割 线 分 割 线 分 割 线 分 割 线 分 割 线 分 割 线 不要二十九块九,不要九块九。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 分 割 线 分 割 线 分 割 线 分 割 线 分 割 线 分 割 线 只需要三块三人民币。你没有听错,9.9 元就可以买到 3 把舒适超巧(Schick Exacta 2)剃须刀。是 3 把完整的剃须刀,不是 1 把刀架 + 3 个刀头。我在京东自营买了 3 把。一次买 12 把的话,1 把仅需 2.075 元。 舒适超巧在旗舰店的价格: 9.9 元 3 把,1 把 3.3 元 14.9 元 6 把,1 把约 2.483 元 24.9元 12 把,1 把 2.075 元 我还在拼多多花 21.42 元买了 15 把,1 把仅需 1.428 元,用了 1 把,质量没问题。 超巧刀头刀架一体,非常轻,可谓是把钱花到刀刃上。超巧只有两层刀片,配合刀头背部的按钮可以推出胡渣,一开水龙头就冲开胡渣了,但是直接把刀片间的位置做空不是更容易清洗吗? 超巧刀头不可旋转,一次刮的距离应该尽量短。润滑条效果差,只能用一次。剃须一次后润滑条变大,有点突出,我们可以用指甲顶把润滑条边缘顶起来,再撕掉。2 层刀片其实是优点。盒式剃须刀的刀片不是越多越好,5 层刀片刮 1 次就相当于 1 层刀片刮 5 次,刮多了容易磨破皮肤。5 层刀片还会把胡子拉起来一点再切掉,用着有点不舒服。 这几次剃须用的皂是 Arko 皂棒,以下是 6 次使用感受。 第 1 次用,锋利度不错,但不太顺滑。剃须后涂明矾,刺激感 1/10 分。 第 2 次用,锋利度还行。剃须后涂明矾,只有下巴周边有点刺激感,刺激感 1/10 分。 第 3 次用,刮到 1 个小伤口(不痛),刮到 1 个小痘痘。剃须后涂明矾,只有那 2 个小伤口痛,刺激感 2/10 分。 第 4 次用,没出血。剃须后涂明矾,极少刺激感,刺激感 1/10。这次感觉比较钝了。 第 5 次用,刀片明显变钝。没刮出血,但是涂明矾后刺激感比较重,刺激感 3/10 分。感觉再继续用就危险了。 第 6 次使用和第 5 次使用发生于同一天。刀片非常钝。我很自然地加大力度刮胡子,下巴有 1 处刮出血。还没涂明矾就觉得脸有点痛了,涂了明矾就更痛了,上唇周围和下巴周围都痛,刺激感 5/10 分。这把刀真的不能再用了,丢了。 用完这把超巧后又用了两三把,没问题。 我的胡子硬,长得快。超巧剃须刀最多用 4 次,只用 2 次会更舒服。 我每天手动剃须 1 次。如果每把超巧用 2 次,每月需要花大概 31 元(30/2*2.075),这只是 1 个中高端盒式剃须刀刀头的价格;如果每把超巧用 3 次,每月需要花费 20.75 元;如果每把超巧用 4 次,每月需要花费大概15.56 元; 虽然超巧剃须刀物美价廉,但也有缺点。超巧的缺点就是对新手来说难用,你需要一定的技术。第一,超巧刀头不可旋转,所以拉长距离刮有弧度的皮肤会容易刮伤。第二,超巧很轻,你可能会不自觉在剃须中用力按压,这可能导致刀片陷入皮肤造成受伤。换个角度想,超巧没有安全功能反而可以纠正错误的剃须手法。技术是可以磨练的,不必过于担心。 盒式剃须刀有个问题,刀头贵。盒式剃须刀的刀片往往用几次就钝,如果一个刀头用 5 次就丢,刀头 30 元,那每月要花 180 元(30/5*30)。超巧哪怕用 2 次就丢,每月才花 31 元。超巧价格低廉,它也许是盒式剃须刀的终点。 超巧也可以是盒式剃须刀的起点,如果你想以最低成本体验盒式剃须刀,那就买超巧和一瓶剃须泡沫。超巧并不适合没经验的新手,我更推荐新手用吉列云感。 为什么标题说盒式剃须刀终点,因为盒式剃须刀只是手动剃须刀的一种,前方还有安全剃须刀和直剃刀等着你呢。 超巧剃须刀评分: 锋利:8/10 顺滑:6/10 安全:4/10 性价比:10/10

2025/9/29
articleCard.readMore

第一次独自开车

总结和感受 # 独自开车第一感觉是紧张,没有老司机在旁边答疑解惑,出状况要怎么办?其实我已经有独自开车的能力,就差迈出这一步。 除了紧张,独自开车的感受就是超爽!随时出发,随时休息。不用在乎乘客的感受,随时大脚油门,管它速度变化平不平稳,反正我开得爽,哈哈。随便开运动模式,顿挫也不管。我很喜欢开车,这次真是过足瘾了。 丙地市区的交通状况较差,道路设计不合理,有时候要在很短的距离变换车道。司机有点野蛮,会挤来挤去。不过在这里开了几次之后就有信心在城市开车了。之前我在乡下开车没问题,到城市就怕。 在城市开车的难点是经常变车道、找停车位。车道的话,看导航画面上方,尽量提前进入合适的车道。太经常看画面会分心,要学会听导航。变道要打转向灯请求旁边车道的司机让路。停车位的话,可以搜索目的地附近的停车场,也可以用百度地图的街景功能看路边有没有停车位。 高速路有不少慢车在最左的快车道,降低通行效率。限速 120 km/h,这些车只有 100 km/h,而且它们前方一望无际。有些慢速车甚至和大车并排,让其他车无法超车。 保持安全车距很重要,这样可以避免急刹和追尾。 这次开车之后信心增长了很多,有勇气独自去陌生的地方了。 # 先去加油站加满油,下午出发。地图显示 180 公里,大概 2 小时,95% 高速。实际用时 2 小时 25 分(中途休息)。 开车前喝了东鹏提神,上高速没多久就下大雨,开了雨刷、近光灯和雾灯。开了大概十多分钟天又晴朗了。 遇到几次道路施工。有些地方没有提前提示,只是接近施工处才出现椎桶。我有点没反应过来,快速看后视镜后换道,幸好没车在旁边车道。下次要尽快变道,如果太接近施工处还是先刹车,直接变道太危险。 这次开车刻意练习扭头观察盲区(shoulder check),汇入主路和变道的时候都会用到。我扭头观察之后,车会左右偏移,不知道我的操作问题还是车的问题。 进弯道前变道至弯道外侧,视野好了很多。开到一半就去服务站休息。喝完剩下的东鹏,吃面包,喝了些矿泉水。 后半程比较多车,遇到危险情况。我在左车道,前方中间车道和右车道有货车并排,中间货车稍微压左线。我自己偏左一点加速超越,有嘟嘟嘟的声音,可能左轮压到排水渠了,车也飘了,吓死我。抓紧方向盘继续开,没撞到左边围栏和右边的货车。下次应该拉开距离,先闪灯鸣笛提醒货车开到车道中间,实在没条件就拉开距离等待机会吧。 驶出高速,在市区开了十多分钟。市区车比较多,要提前打转向灯请求变道,不然有时候观察很久也没有变道条件。电动两轮车的行驶轨迹比较随机,要多加注意。 到一个路口前时速 70 km/h,我想着降挡减速。从 D 挡挂到 L 挡,发动机嗡嗡响,转速涨到 5000 多,吓得我赶紧踩刹车,生怕转速超过警戒线。 # 早上 11 点左右出发。先找好目的地附近的停车场,高德地图显示 84 公里,1 小时 13 分,高速 81%。实际驾驶了 1 小时 21 分(不在最后一个高速服务站休息一会,没算停车花费的时间)。 第一次从乙地开车到丙地,有点紧张。 在高速路基本没什么问题,就是遇到一辆匝道汇入主路的车连续变道到左车道,我闪灯制止了。11 点多的阳光很晒,手的皮肤被晒得有点疼。 离开高速前 2 公里,右车道有货车,我先从中间车道超越再转右车道。这个过程比较匆忙,要是右侧车多很可能没机会变道。2 公里很快走完,下次还是老老实实在右道吧,跟着大货车也不会很久。 离开高速路后开了一段乡村道路,弯弯绕绕的,急刹了一次,后车司机按喇叭了。遇到一辆靠右的大货车,车打了左转灯但没动,我急刹后等待,两三秒大货车都不动。我往左借道超车,大货车就慢慢左转了,猛踩油门超越,有点后怕。 然后进到市区,因为提前导航到停车场,所以不是很紧张。 进停车场停好车,突发感觉不对劲。我以为找到是地面停车场,结果进到地下停车场了。换了另一个地图应用,刚出地下停车场,就发现地上停车场在右边,原来一开始来的时候没看到。开进去,停车位的线不明显,我参照周围车辆停车。第一次停的时候挡到前面的电动车位,又后退了一点。 # 下午 6 点多出发去探亲,才 8.5 公里的路,开了半小时,下班时间的市区真堵车。这段路开得我头皮发麻,车挤车,导航时不时识别不到我在哪个车道。变道的时候扭头看盲区,脖子都累了。市区好多车,扭头看盲区很重要,只看后视镜是不够的。 导航显示前方路口右转,我提前走到最右边。突然前面有临时停车的车辆,急刹,看后视镜,扭头看盲区,左转。开到路口前一两百米,右转道路才出现。这是什么设计呐,非要在路口前面变道吗! 好多电动车钻缝隙,你们不怕小车,我怕你们。 这段路真是锻炼车技,经常开几百米就要变车道,反应要快,打灯观察变道一气呵成。开到目的地,看了一下车,没剐蹭。 # 和亲戚去吃饭,客人多,停车位不足。亲戚让我停在一辆车旁边,他把车停到外面。 离开饭店的时候,走错方向,只好在窄路掉头,在两个方向的车来到之前搞定,史上最快的掉头。 开车去景点,还是经常要换车道。快到路口的时候想往右边车道,突然发现地上是实线,又打方向回来。这次没观察就打方向了,幸好没事。 开车去乙地,地图显示,61公里,50分钟。实际开了52分钟。 # 去一个地方办事,说是有停车位,去到那里,门口都停满了。停了周围的停车位。 去超市地下停车场,消费后到自助机器输入车牌号,可以免费停车 2 小时。 买完东西,到地下停车场,找了很久车。到陌生的地方还是要拍视频拍照记录好停车位置。 从丙地到甲地,选了另一条有段国道的路线,出高速走 12 公里国道。这段国道很多弯,晚上光线不好。今天又遇到前方弯道超车的,超讨厌这样的司机,这种人不出事完全是因为别人的忍让。看来进弯道前还是要开慢点,再加上闪灯和鸣笛。

2025/9/11
articleCard.readMore

吉列云感:适合新手的剃须刀

在京东自营买了吉列云感(SkinGuard,绅适)剃须刀。1 刀架 + 2 刀头,附赠 2 瓶 20g 云感洗面奶,共 69.7 元人民币。这次买的刀柄产地为波兰,刀头产地为德国。 云感剃须刀的特点是舒适安全,有双层刀片,刀片间有减压梳。云感用着确实不容易刮伤,给了我逆刮胡子的自信。我不会逆刮胡子,随便试试,居然只是有轻微刮伤,没有明显出血。 两层刀片的剃须效果一般,剃须时需要多刮几遍。刀头背面有精细修毛刀。 用大概十多次,刮胡子的时候感到有阻力,用更大力刮,嘴唇上面那里刮出三四个伤口。换了新刀头之后刮胡子就像一开始那样顺畅。 云感可以用锋隐(Fusion)系列的刀柄。锋隐致顺(ProGlide)刀柄可以像左右两侧旋转刀头,把云感刀头安上去就更安全了。 附赠的云感洗面奶难闻,没剃须啫喱好用,顶多应急的时候用。 如果你是第一次尝试手动剃须刀,推荐你用云感,减少受伤机会,减少挫败感。 最后推荐大家看大佳刮胡的视频评测:【刮鬍刀評測】吉列刮鬍刀的誠意之作 吉列紳適 GILLETTE SKINGUARD RAZOR REVIEW - YouTube。

2025/9/5
articleCard.readMore

赌气跟随超车的惊魂时刻

开车到十字路口,我左转上坡时,有辆五菱右转挨着我嗖的一下上坡了。明明我左转有优先权,气得我深踩油门跟上去,准备用远光灯和喇叭警告五菱司机。 坡道宽度刚好能过两辆小车,五菱前面有台两轮电动车,它开到左边超越电动车。我也跟着五菱超车,五菱超车完回右边之后,我前面出现一台三轮摩托车,damn,吓死我😱,好怕撞到!我稍微右转,夹在摩托车和电动车之间刀片超车了。 在我惊魂未定的时候,五菱已不见踪影。跟随超车真危险,因为视野受限(前车能躲障碍物,我可能躲不过)和没有安全距离(前车急刹,我就追尾)。开车赌气也不好,要是心态冷静就不会经历这些了。

2025/6/29
articleCard.readMore

开自动挡不看挡杆换挡教程

看到这篇文章你可能会想:「开自动挡挂 D 挡就走了,切换到 P/R/N 挡时车子都停下来了,看着挡杆也无妨。有必要不看挡杆换挡(盲操挡杆)吗。」当然有必要,不看挡杆换挡更帅啊,也更安全,更快。自动挡的前进档不止 D 挡,还有 S 挡、M 挡、L 挡。开车时需要根据情况换挡,低头看挡杆换挡会很危险,时速 60km/h 时,看 2 秒挡杆,相当于闭眼开了 33 米。下面是不看挡杆换挡的教程。 第一步,学会左手单手开车。左手可以抓方向盘的 6 点、9 点或者 12 点位置。不需要一直左手开车,换挡的时候控制好车就行。 第二步,记住档位顺序。以轩逸经典 2022 款的机械档杆为例,挡位从上到下是 P、R、N、D(Ds1)、L。进入N挡和D挡不需要按解锁键,这是盲操的关键,知道这个之后盲操一般就是动 1 格或者推拉到底。仪表盘会显示目前档位,换挡后可以看仪表盘确认是否进入目标挡位。 介绍几个常用操作: 起步(P->D): 踩刹车,按解锁键,下拉挡杆 1 格,进入 R 挡。不要松刹车,以免倒车。 松开解锁键,下拉挡杆到底(没按解锁键,不会进 L 挡),进入 D 挡,松刹车。 为什么不按下解锁键拉 3 格呢,因为这样要在心里数,会分心,力度也不好控制。 停车(D->N->P): 踩刹车,上推挡杆到底进入 N 挡,松刹车。 踩刹车,按住解锁键,上推挡杆到底,进入 P 挡,松刹车。 进入陡坡(D->L): 按解锁键,下拉到底,进入 L 挡。 倒车(D->R): 踩刹车至车停下来,上推挡杆到底,进入 N 挡。 按住解锁键,上推挡杆 1 格,进入 R 挡,松刹车。 临时停车等绿灯2(D/L -> N): 踩刹车至车停下来,上推挡杆到底,进入 N 挡。 拉起手刹,松刹车。 其他操作我就不写了,留给你自己想。 第三步,练习。先原地练习,熟练后再去空旷安全的路上练。记住进 N 挡 和 D 挡不需要解锁键,要么动 1 格,要么推拉到底。 自己练的话,可以给自己定一个目标挡位,从其他挡位切进去。也可以设定一个起始挡位,切换到其他挡位。还可以叫朋友给你随机播报挡位,你来换挡。 盲操其他类型的挡杆应该也差不多吧,就是单手开车、记住挡位顺序、练习。 Ds 是轩逸的运动模式,在 D 挡状态时按下挡杆左边的小按钮即可使用。轩逸也有运动模式,想不到吧。 ↩︎ 在路口遇到红灯,明明是在等绿灯,为什么大家都说等红灯呢。 ↩︎

2025/6/28
articleCard.readMore

英语的语气(陈述语气、祈使语气、虚拟语气)

英语的常见语气(mood)有陈述语气(indicative mood)、祈使语气(imperative mood)、虚拟语气(subjunctive mood)。 # 陈述语气用于陈述事实。 例句: The cat ate a mouse. 那只猫吃了一只老鼠。 # 祈使语气表示希望或者要求。祈使语气中开头一般是 you must 或者 you should,但这部分被省略,所以祈使语气以动词原形(不含 to 的动词不定式)开头。 例句: (You must) Watch out! A car is coming. 小心!有辆车来了。 (You mustn’t) Don’t run! 别跑! # 虚拟语气表示期待或者非事实的情况,一般用于条件句。 使用虚拟语气时需要将动词倒退一个时态来表示非事实,例子: If I were rich, I would buy a big house. 如果我有钱,我就买大房子。——现在时间非事实,其实我没钱,也没买大房子。 时态倒退的动词写法是表示虚拟的标记。如果虚拟语气不改变动词的写法,那就和陈述语气一样,听者分不清是真是假。正是奇怪的写法才能让人知道这是虚拟语气。至于为什么用时态倒退的写法,我怎么知道可以理解为时光倒流才能改变已经发生的事情(这只是帮助理解的比喻)。 # 使用与现在事实相反的虚拟语气时,动词写法要往过去倒退一个时态,也就是使用过去时的写法。条件句用过去时,主句用过去时助动词。注意 be 动词的过去式要用 were,不过也有人用 was 这样不正式的用法。 句型: If + 主语 + 过去时动词, 主语 + would/could/might/should/ought to + 原形动词. 非事实例句: If I were rich, I would buy a big house. 如果我有钱,我就买大房子。 If I had an apple, I could give it to you. 如果我有一个苹果,我可以给你。 事实例句: Because I am not rich, I can’t buy a big house. 因为我没钱,所以无法买大房子。 I can’t give you an apple, because I don’t have one(one 指代前面的 apple). 我不能给你一个苹果,因为我没有。 # 使用与现在事实相反的虚拟语气时,动词写法要往过去倒退一个时态,也就是使用过去完成时的写法。条件句用「had + 过去分词」,主句用「助动词过去时 + have + 过去分词」。 句型: If + 主语 + had + 过去分词, 主语 + would/could/might/should/ought to + have + 过去分词. 例句: If I had studied harder, I would have passed the exam. 要是我当时更努力学习,我就通过考试了。 # 将来的事尚未发生,所以不存在将来事实。所谓与将来事实相反的虚拟语气,就是未来事件的低可能性和有一定可能性。下面先介绍低可能性的用法。 使用与将来低可能性的虚拟语气时,如果动词直接倒退一个时态就变成现在时了,这样就无法和陈述语气区分开。要借助助动词表示将来虚拟语气,条件句用 should(should 是 shall 的过去时,此处的 should 没有「应该」的含义)或者 were to(be going to 的一种变体),主句用过去时助动词(表示低可能性)。If…should… 可翻译为「万一」。 句型: If + 主语 + should/were to + 原形动词, 主语 + would/could/might/should/ought to + 原形动词. 例句: If I should win the lottery, I would buy a car. 如果我中了彩票,我会买一辆车。——将来中奖的可能性低。 If aliens were to invade the Earth, humans might be defeated. 万一外星人入侵地球,人类可能被击败。 # 表达将来一定可能性时,条件句用 should,主语用现在时的助动词。 句型: If + 主语 + should+ 原形动词, 主语 + will/can/may/should/ought to + 原形动词. 例句: If it should rain, I will stay home. 万一下雨,我就待在家里。——有可能下雨,如果下雨了我就待在家里。 # 从句和主句的时间或者语气可以不一致。 例句: If I had invested in Bitcoin in 2010, I would be a billionaire now. 要是我 2010 年投资了比特币,我现在就是亿万富翁了。——前半句与过去事实相反,后半句与现在事实相反。 I should have paid for the meal, but I was too mean. 我应该请客,但我那时太吝啬了。——过去时间,前半句非真实,后半句真实。 # 如果条件句中有 had/should/were,可以将 if 省略,将 had/should/were 置于主语前。 例句: If I were you, I would accept the job. = Were I you, I would accept the job. 如果我是你,我会接受这份工作。——与现在事实相反。 If they had known the truth, they would have stopped him. = Had they known the truth, they would have stopped him. 要是他们知道真相,就会阻止他了。——与过去事实相反。 If you should need help, I would give you a hand. = Should you need help, I would give you a hand. 万一你需要帮忙,我会帮你。——与将来事实相反。 # 虚拟语气也可以归类到条件句(conditional sentences)中,所以在这里顺便介绍一下条件句。 英文条件句可以分为 4 类。 零条件句(zero conditional):表明事实与真理,从句与主句都用一般现在时。 第一条件句(first conditional):表明肯定的预测,条件句用一般现在时,主句用将来时(简称「主将从现」)。 第二条件句(second conditional):与现在或者将来事实相反,也就是现在或者将来的虚拟语气。 第三条件句(third conditional):与过去事实相反,也就是过去的虚拟语气。 零条件句和第一条件句的例句: If you don’t eat for a long time, you become hungry.(零条件句) 如果你长时间不吃东西,你会饿。 If you make a mistake, someone will let you know.(第一条件句) 如果你犯错,有人会告诉你。 # 《赖氏经典英语语法新版》,2017 年 2 月第 1 版 《旋元佑文法》,2021 年 3 月 初版 英语"虚拟语气"就是这么简单(看完就懂!) - YouTube(哔哩哔哩) English conditional sentences - Wikipedia

2025/6/25
articleCard.readMore

开车通过路口和人行道的注意事项

进入路口和人行道前松开油门,准备刹车减速,必要时刹车。 身体前倾扩大视野,左右观察路况。 遵守交通规则,按照地面标志和红绿灯通行。 不要超越其他车道前面的车(不超齐头车),它会阻挡我们的视野,超过它可能就撞到横穿的车辆。如果前面的车刹停,司机可能在避让行人或者车,此时我们贸然超车就很危险。 通行优先级(从高到低):行人 > 直行车 > 左转车 > 右转车。 转弯要打转向灯。 如果转弯时如果自己通行优先级较低,就减速停车等待。 如果直行时有车接近,按喇叭警示,看情况加速或者减速。 转弯时不要跨越车道。比如:从左边第一车道左转,左转完还是在左边第一车道,不能在第二车道。 左转转大弯,右转转小弯。也就是左转时靠近路口中心点左侧,右转时远离路口中心点。

2025/6/17
articleCard.readMore

触发 ABS,克服急刹恐惧

我刚开车的时候不敢踩尽油门(感觉会很快),在朋友的鼓励下试着踩尽油门,发现其实加速没有我想象的快,踩多几次也就不怕了。后来开一台动力更强的车,借道超车踩尽油门,速度有点快,吓死我。还是得适应不同的车。 油门敢踩尽了,刹车倒是不太敢踩尽,怕车子失控。虽然知道车子有 ABS(Anti-lock Braking System,防抱死制动系统),急刹也不会翻车,但心里还是害怕。 今天下雨,就试试踩尽刹车触发 ABS 吧。开车去一个没人没车的地方,戴好安全带,观察四周,确定没人没人,开始尝试。用户手册说 ABS 在时速 5~10 km/h 以上才会触发,还要用力踩下刹车并踩住。 一开始上坡速度是 20 km/h,用力踩刹车,没有触发 ABS。换成下坡,挂 D 挡,踩尽油门,时速到 30 km/h 的时候用力踩尽刹车,刹车踏板快速反复上下抖动(其实就是快速点刹,比人脚快多了),发出嘟嘟嘟的声音,此时我还是踩尽踏板。再试了两次,也触发 ABS 了。 虽然观察路况提前刹车比较好,但遇到突发状况还是需要急刹,试过 ABS 之后就不怕急刹了。 ABS 启动时会刹车踏板会弹脚,没遇到过可能一紧张就松开刹车了,正确做法是一直踩刹车。如果你还没试过,建议找个安全的地方试试。 也许是太紧张,练完后呼吸胸口有点痛,半小时之后就没事了。这次有进步,之前练习急刹,踩了几下,没踩出 ABS,我就已经晕车想吐了。这次只是肚子不太舒服,还没晕车想吐。

2025/6/14
articleCard.readMore

从看蔡徐坤的迷因到听蔡徐坤的歌

第一次知道蔡徐坤,是因为他的迷因(梗)太火爆了,在网上经常看到「鸡你太美1」和「蔡徐坤打篮球」的迷因视频。我还挺爱看蔡徐坤的迷因,哈哈。 蔡徐坤的迷因影响力不小,我在现实中好多次听到小学生把用「坤」指代「鸡」。有武术门派叫坤门。有时间单位叫坤年(两年半)。 后来看到蔡徐坤发律师函给哔哩哔哩表示滥用肖像,我就感觉他有点小气。我对蔡徐坤的印象比较片面,感觉他就是流量明星,没多少才华。 再后来在《奔跑吧》节目看到蔡徐坤,感觉这个认真的男人还蛮帅。蔡徐坤有疑似强迫堕胎的争议之后,《奔跑吧》延迟播出,播出后蔡徐坤的画面都删除了。蔡徐坤仍然在新加坡开了场演唱会。之后就没看蔡徐坤有什么公共活动了。啊,迷因没有新素材了。 偶然在 Youtube 听到蔡徐坤在 2024 年发布了 Remedy。嗯,好听耶,MV 也很有格调,蔡徐坤的英语非常标准。原来蔡徐坤是歌手!单曲循环听了好几天,还去 KTV 唱过两三次,嘻嘻!情人我也听了,在 KTV 唱感觉有点油腻。 最近发现蔡徐坤出了新歌 Deadman,一样好听(我不懂音乐,只能这样夸了),MV 画面更精良。1分钟开始那几段受伤画面太美啦!又开始单曲循环了,希望下次去 KTV 能点到这首歌。 「只因你太美」这句歌词听着像「鸡你太美」。 ↩︎

2025/6/4
articleCard.readMore

第一次交通事故

前段时间经过限宽墩的时候撞到右前轮,车子弹出去,方向盘无法控制右前轮。我没事,车子也没撞到其他东西。 下面是处理事故的大致过程: 开危险警示灯 报交警 拍照(车子四边,坏掉的轮子远近各一张,共六张) 尝试把车子往路边开,只挪动了一点 交警到位,帮忙推车,维护交通秩序 交警叫修理厂的师傅来把车子拖到修理厂(也可以拖到交警的停车场,但是最后还是要拖出来去修理厂,干脆就拖去修理厂吧) 我和车子到修理厂后,拿上行驶证和驾驶证(可以用电子版)去交警那里要个交通事故责任认定书(我全责) 报保险,让维修师傅和保险那边沟通(其实一开始就可以报保险了) 等五六天车就修好了,维修费和拖车费都是保险报销 事后想了下,应该是过限宽墩时没完全摆正车身,车速太快(三四十 km/h 吧)所以碰到一点限宽墩车子就弹出去了。开快大概是因为自己处于开车新手膨胀期,之前过了几次那个限宽墩都没问题,就过度自信了,通过时没有降低到合适的速度,也没怎么观察。 幸好无人员伤亡,也没损害别的车子。以后不要过度自信。上哔哩哔哩学习了过限宽墩的方法,也就是车身摆正,尽量偏左,但不要碰到限宽墩左边,这样右边肯定够位置。这次撞限宽墩之后我都害怕再经过那个墩,后来按照方法慢慢开了几次又恢复信心了。

2025/6/4
articleCard.readMore

自动挡挡位的英文全称、含义和用法

挡位含义 # P(park):驻车挡位,锁定变速器齿轮,通常配合手刹使用,长时停车时使用。 R(reverse):倒挡,向后行驶时使用。 N(neutral):空挡,变速器齿轮分离,发动机不提供动力。临时停车(如等红绿灯)搭配手刹使用,被拖车时也使用 N 挡。 D(drive):前进挡,向前行驶时使用。 L(low):低速挡,动力强速度慢,适合上陡坡和下陡坡,相当于 1 挡或者 2 挡。 S(sport):运动模式,动力更强的 D 挡,转速提升,更费油;此挡位下更容易降挡,更难升挡。适合超车、上坡(动力强)、下坡(有发动机制动,避免过多使用脚刹使刹车片过热导致刹车失灵)。如果下坡还是过快就改用 L 挡。 M(manual):手动模式,用法和手动挡汽车类似,司机使用拨片或者挡杆切换挡位,上下坡可以用低挡位,超车可以降挡。 备注:N(neutral)的字面意思是中立,可以理解为车子不进不退。 # 建议自动挡司机不要只用 D 挡,了解一下手动挡的挡位和自己车上的 L 挡、S 挡、M 挡,下坡的时候使用低挡位利用发动机制动。 D 挡、L 挡、S 挡、M 挡是一组前进挡,和 P 挡、R 挡、N 挡之间切换需要刹停车子继续踩刹车来切换。 D 挡、L 挡、S 挡、M 挡之间切换不需要踩刹车。注意不要在高速时切换到 L 挡,那样会导致发动机转速过快,建议刹车降速到 40 km/h 以下再换 L 挡。

2025/5/30
articleCard.readMore

新手开车感受

慌张 # 虽然拿到了自动挡驾照,但在驾校只是学了通过驾考的方法,真的开车感觉很慌张,怕撞人或者撞车。我请朋友教我开车,练习几次之后好多了,但还是判断不好车的左右距离。我看了「坐在车内,准确判断左右前后车距的方法,新手掌握后避免各种剐蹭 - 哔哩哔哩 bilibili」这个视频,在车上画了两根线1,东西在线外就不会撞到。能判断左右距离之后基本就不慌张了。 # 学会开车之后感觉很开心,开小车可以免于日晒雨淋,可以自由地去更远的地方。开小车也更安全,毕竟是铁包肉,车里还有安全带和安全气囊。 # 开车多了,在路上就容易感到愤怒,因为很多交通参与者不讲规矩,通常不尊重路权(道路优先权),也有影响别人驾驶。 举些例子: 小车不打转向灯突然切换车道 塞车时有前车有空位,马上超车挤进去 车在晚上一直开远光灯,对向来车时也不调成近光灯,无视对向来车开远近交替灯提醒 电动车骑手在十字路口想着两点直线距离最近,不观察路况,不打转向灯 行人不走人行道和人行横道,直接走在马路上,而且不靠边 行人穿过马路不观察,而且跑得飞快 今年的粗话肯定九成都是在车上说的,马路上的傻屄怎么那么多啊!开车不仅要自己开好,还要避开潜在危险。要观察路面情况,预测交通参与者的行为,还要设想前方道路的情况,开着开着就感觉脑子好累。 调过座位之后这两根线没那么准了。 ↩︎

2025/5/22
articleCard.readMore

自动挡半坡起步方法(手刹、左脚刹车、右脚刹车、上坡辅助、自动驻车、电子手刹)

上坡起步的难点在于车子因重力而后溜,所以要先使用脚刹或者手刹防止车子后溜,再让车子有前进的力,这样松开刹车时车就不会后溜。虽然 C2 自动挡驾考不考上坡起步,但实际开车会用的上,比如:停车场出口、坡道堵车。 本文介绍上坡起步的 3 个手动操作方法(手刹法、左脚刹车法、右脚刹车法)和 3 个电子辅助方法(上坡辅助法、自动驻车法、电子刹车法)。使用电子辅助方法前请看用户手册确认是否有相关功能:上坡辅助(hill-start assist control / HAC)、自动驻车(auto hold)、电子手刹(Electronic Parking Brake / EPB),如果没有相关功能,请使用手动操作方法。 注意:因为我开的车没有电子辅助功能,所以我只测试了 3 个手动操作方法。3 个电子辅助方法是我看资料总结的,如果你测试能行,欢迎留言告知,谢谢! 上坡结束后可以从 L 挡调到 D 挡。L 挡和 D 挡都是前进挡,所以换挡时不需要刹车。 起步除了感觉车子是否移动,还可以参考转速表,一般 1500~2000 转之间即可。建议先在安全的平地练习,熟练后再去坡道练习。 # 右脚踩刹车,拉起手刹。 松开刹车,确保车不后溜。车后溜则说明坡道太陡,手刹制动力度不足,请改用脚刹法。 右脚踩刹车,调到动力更强的 L 挡1。 左手抓稳方向盘,右脚踩油门,感觉车子动了就用右手放下手刹继续踩油门,右手放回方向盘。 # 左脚踩刹车,调到 L 挡,放下手刹,左脚一直踩刹车。如果右脚已经踩着刹车,那就右脚踩着刹车慢慢往右挪动,腾出空间让左脚踩上刹车。 右脚踩油门,感觉车子动了就左脚松开放到一边,右脚继续踩油门。 在平地以这样的方式用 D 挡起步速度更快,这叫弹射起步。请勿在上坡堵车走走停停时使用左脚刹车法,多次使用会让你分不清该用哪只脚踩刹车。 # 右脚趾踩刹车,调到 L 挡,放下手刹,右脚趾一直踩刹车。 以右脚趾为中心,逆时针摆动右脚,让右脚跟碰到油门。 右脚跟踩油门,感觉车子动了就迅速把右脚滑到油门,继续踩油门。现在已经松开脚刹了。 因为不同人的脚有差异,不同车的脚刹和油门也有大小、距离和高度的差异,所以并没有放之四海皆准的跟趾动作。我自己脚踩右半边脚刹,这样脚跟才容易踩到油门。有些人脚跟踩脚刹,脚尖踩油门。要多多练习才能发现适合自己的跟趾动作。 跟趾动作最帅最方便,适合上坡堵车走走停停的情况。 # 上坡辅助就是车子在斜坡时,司机松开脚刹,车子会自动刹车两三秒,此时司机可以踩油门起步。 步骤: 放下手刹,右脚踩刹车,调到 L 挡 右脚抬起后车子自动会刹车两三秒,踩油门起步 # 如果需要在坡道上倒车(车头朝向下坡),就使用前面的手刹法、左脚刹车法、右脚刹车法,只需要将挡位从 L 挡换成 R 挡。 反向上坡起步的使用场景有: 自己停好车了,后来前面停的车离自己的车非常近。如果松开刹车去踩油门倒车,可能车子前溜就撞到前车了。此时需要稍微倒车给自己腾出空间转向。如果自己的车被前后夹击,可以去交管 12123 应用一键挪车。 坡底有障碍物,自己的车离障碍物太近,需要倒车给自己的车腾出空间转向。 有次女朋友开车下坡,坡底左前方有辆车,她右转,还是空间不够。她下车换我开,我给她展示了反向上坡起步,然后右转开出去了。她投来崇拜的目光,说我太帅啦。 # 手刹法是三个半坡起步方法中最稳妥的,但是拉了手刹松开脚刹的一瞬间车还是会溜一点。自己的车离溜车方向的障碍物太近时,同时用手刹法和脚刹法就更稳妥,也就是踩刹车、拉手刹、踩油门、松刹车、松手刹。 # 自动驻车开启时,司机刹停车子再松开刹车,车子会继续刹车,踩油门就会解除刹车。 步骤: 放下手刹,右脚踩刹车,调到 L 挡 松开刹车,踩油门起步 # 踩油门时会自动解除电子手刹,我们可以利用此特点来上坡起步。 步骤: 右脚踩刹车,调到 L 挡 踩油门,电子手刹会自动解除 如果车子有手动模式(M 档),使用手动模式的 1 挡。 ↩︎

2025/5/21
articleCard.readMore

C2 自动挡汽车驾照考试经验

过完年拿到证了,非常开心!和大家分享一下备考的经验。 # 考试共四个科目,一般按顺序考试,科目一和科目四是笔试,科目二和科目三的实操。考完科目三可以当天考科目四,想快点拿证就在考科目三之前做好科目四的习题。 # 做完驾考宝典的精简 500 题(需要开通 VIP),然后一直做模拟考试,连续两次过了 90 分就可以考虑报名考试,报名后继续做模拟考试。 # 科目二我把教练说的步骤逐字记到笔记应用,自己看着步骤练习,练多了就记住了。 把步骤记下来之后就可以自己独立练习。倒车入库和侧方停车都可以自己中途暂停下来看对不对(记得拉手刹),直角转弯和曲线还是有人帮忙看比较好。 考试前在考场模拟练习熟悉场地。 考试开车不要太慢,我第一把倒车入库超时就不合格。不合格之后就继续走完全程,当练习。 # 将路线图和步骤打印出来看,用 Anki 背,但是我感觉步骤太多了,我只记了转弯、掉头和变道,考试的时候也够用。如果转弯、掉头和变道也记不住的话,就只记超车前要在哪个车道(超车时在左道会考试失败,因为在左道无法超车),其他听语音。 学校路段、人行横道、公交车站前要点刹(轻踩刹车踏板)。这没有语音提示,要自己记住。 变道和转弯要打转向灯,中途方向盘大多了会灭灯,这时赶紧再次打灯。 学会用雨刮器,不然下雨你就慌了。 有危险自己赶紧刹车,安全员刹车就导致考试不合格。 考试前在考场模拟练习熟悉场地。 # 科目四应该和科目一方法一样,就是做题。我考完科目三去没做题就去考科目四也通过了。 # 上车: 上车调整座椅 戴安全带 调后视镜 起步: 踩住刹车 调到前进档 放下手刹 松开刹车踏板 下车: 踩住刹车 拉起手刹 调到空档或者停车档 松开刹车 起步要先调档在放手刹。如果先放手刹,再调档,不小心调到倒车档就考试失败。下车先拉手刹也是一样的道理。 # 考科目二在封闭场地,不会撞车或者撞人,最差的结果就磕碰到车。 考科目三在自己的道上好好开,你不会撞到别人,正常人开车也不会撞你的。开得慢时安全员可能在一边唉声叹气,忽视他,继续开车。 如果你还是很紧张,那就不管了,考试走完全程就好。 # 前面都是一些应试经验,拿证和真的会开车还有段距离,最好请人带你开车,多练习。 # 科目一第一轮 100 分 科目二第一轮倒车入库超时,第二轮 100 分 科目三第一轮 90 分(靠边停车扣了 10 分) 科目四第一轮不合格,第二轮 90 分

2025/5/14
articleCard.readMore

再次用手动剃须刀

我第一次剃须用的是手动剃须刀,剃须的时候容易出血,就改用电动剃须刀了。目前用的电动剃须刀是米家 S301,价格为 116.49 元人民币。虽然用电动剃须刀不会刮出血,但是用了半年左右刀头就磨损过度,剃须时总把胡须扯起来,疼死了。 上次买刀头花了 63.6 元,现在看要 79 元,还要 10 元运费,这价格和买新剃须刀差不多了。电动剃须刀还有一个我非常讨厌缺点:胡须残渣在刀头里会发臭,开始发臭后洗不掉臭味。如果我每次剃完胡子都洗刀头又要等它晾干,非常不方便。 综合以上原因,我决定再试试手动剃须刀。在京东买了 36.9 元的吉列威锋 3(1 刀架、3 刀头)、16.9 元的吉列剃须泡沫(50g),共 53.8 元,优惠后是 45.93 元。第 1 次用下巴刮出 4 个伤口,第 2 次用下巴刮出 1 个伤口,第 3 次开始基本没刮出伤口了,谢天谢地。我之前刮下巴是从上往下刮,容易刮伤,后面改成横向刮就没事了。侧面和嘴唇上下都是从上往下刮,稍微倾斜。脖子从下往上刮,有点阻力,要小心点。 刮完胡须洗脸,一照镜子,非常惊喜,刮得比电动剃须刀干净多了,剃须过程也更有乐趣。没想到三十多元的手动剃须刀有如此效果。这样刮一遍就很干净了,反方向刮一遍会更干净,但是反着拿剃须刀好难,算了。 用了 2 个星期手动剃须刀,感觉它比电动剃须刀好多了:刀架刀头更便宜、容易清洗(用在酒店拿的一次性牙刷刷几下,用水冲洗)、洗了很快干(每天剃须 3 次,用的时候剃须刀都是干的)、每次用了都洗就不会臭、剃须干净很多。手动剃须刀也是有缺点的:需要学习使用技巧、更费时。 手动剃须刀刀片裸露在外,所以带走的时候要防止它刮到行李,于是我就花 35.91 元买了个吉列致顺剃须刀旅行盒(威锋 3 也能放进去)。其实旅行盒的钱也是可以省的。带走剃须刀的时候可以把刀头取下来放进刀头盒,再把刀头盒用塑料袋包着防止刀头掉落,这样应该就安全了。

2025/5/13
articleCard.readMore

给一加 Ace 3 升级固件

我的一加 Ace 3 用的是 PixelOS 系统,此系统不包含固件,所以要自己升级固件。 固件通过 fastboot 和 fastbootd 安装,所以先测试 fastboot 和 fastbootd: 将手机通过数据线连接到电脑 按住音量下键和电源键开机进入 fastboot 运行 fastboot devices,确定手机处于 fastboot 运行 fastboot reboot fastboot,进入 fastbootd 运行 fastboot devices,确定手机处于 fastbootd 我的手机目前系统版本是 PixelOS_aston-15.0-20250424,固件是 PJE110_15.0.0.500,固件要升级到 PJE110_15.0.0.701。 安装过程: 按住音量下键和电源键开机进入 fastboot 在这里下载固件,这次下载 PJE110_15.0.0.701,下载固件后解压 电脑是 Linux/macOS 系统就运行固件文件夹里面的 install_images.sh,Windows 就运行 install_images.bat 安装记录(写给自己看的): PJE110_15.0.0.500 -> PJE110_15.0.0.701(系统版本:PixelOS_aston-15.0-20250424) PJE110_15.0.0.701 -> PJE110_15.0.0.801(系统版本:PixelOS_aston-15.0-20250506) PJE110_15.0.0.801 -> PJE110_15.0.0.820(系统版本:PixelOS_aston-15.0-20250621) PJE110_15.0.0.820 -> PJE110_15.0.0.840(系统版本:LineageOS 23.0-20251012-NIGHTLY-aston) PJE110_15.0.0.840 -> PJE110_15.0.0.870(系统版本:LineageOS 23.0-20251107-NIGHTLY-aston)

2025/5/6
articleCard.readMore

解锁 Redmi K40S(HyperOS 1.0)的 bootloader

从 HyperOS 开始,解锁 bootloader(引导程序)的难度大大增加,不过还是有办法绕过限制。建议想解锁的读者先暂停系统更新和应用更新,以免升级后无法绕过限制。 这台 Redmi K40S 的系统版本是 HyperOS 1.0.8.0.ULMCNXM。以下是解锁方法: 插入手机卡。 下载设置应用,解压后传到手机安装,成功。 根据电脑系统下载 HyperSploit 并运行,根据提示操作。 这台手机显示验证失败,电脑显示 Error 401: Xiaomi account credentials expired, login again。 退出账号,登录账号。再次运行 HyperSploit,这次电脑显示绑定成功了。运行小米官方解锁工具(备用版),提示等待 168 小时。 手机卡就留在这里了1。 打开应用商店,关闭自动升级。打开系统更新,关闭自动下载和夜间安装。让手机一直开机。 等够 7 天后再次运行小米官方解锁工具,成功啦! 重启完居然显示有账号锁,需要联网后验证小米账号密码。我的手机卡设置了密码,系统它又不让我输入手机卡密码(这太傻了吧!),这样无法用手机卡的网络。只好连接 WIFI 了,输入密码后进入系统,再退出小米账号。最后装上了我最喜欢的 LineageOS 系统。 我不确定是否要一直插卡,只是感觉这样比较稳妥。 ↩︎

2025/3/13
articleCard.readMore

英式英语音标

本文采用 DJ 音标。英式英语中,元音有 20 个,辅音有 24 个,常用辅音连缀有 4 个。 元音:/iː/, /ɪ/, /e/, /æ/, /ɑː/, /ɔː/, /ɒ/, /uː/, /ʊ/, /ə/, /ʌ/, /ɜː/, /eɪ/, /aɪ/, /ɔɪ/, /əʊ/, /aʊ/, /ɪə/, /eə/, /ʊə/ 辅音:/p/, /b/, /t/, /d/, /k/, /ɡ/, /f/, /v/, /θ/, /ð/, /s/, /z/, /ʃ/, /ʒ/, /h/, /tʃ/, /dʒ/, /m/, /n/, /ŋ/, /r/, /j/, /w/, /l/1 辅音连缀:/ts/, /dz/, /tr/, /dr/ # 元音包括单元音和双元音。 # /iː/ see /siː/ /ɪ/ bit /bɪt/ /e/ bet /bet/ /æ/ cat /kæt/ /ɑː/ car /kɑː/ /ɔː/ law /lɔː/ /ɒ/ lot /lɒt/ /uː/ blue /bluː/ /ʊ/ put /pʊt/ /ə/ sofa /ˈsəʊ.fə/ /ʌ/ cup /kʌp/ /ɜː/ bird /bɜːd/ # /eɪ/ day /deɪ/ /aɪ/ my /maɪ/ /ɔɪ/ boy /bɔɪ/ /əʊ/ go /ɡəʊ/ /aʊ/ now /naʊ/ /ɪə/ here /hɪə/ /eə/ care /keə/ /ʊə/ tour /tʊə/ # 辅音包括爆破音、摩擦音、破擦音、鼻音、近音、边音。 # /p/ pen /pen/ /b/ bat /bæt/ /t/ top /tɒp/ /d/ dog /dɒɡ/ /k/ cat /kæt/ /ɡ/ go /ɡəʊ/ # /f/ fish /fɪʃ/ /v/ van /væn/ /s/ see /siː/ /z/ zoo /zuː/ /ʃ/ she /ʃiː/ /h/ hat /hæt/ /ʒ/ measure /ˈmeʒə/ /θ/ think /θɪŋk/ /ð/ this /ðɪs/ # /tʃ/ chip /tʃɪp/ /dʒ/ jam /dʒæm/ # /m/ man /mæn/ /n/ not /nɒt/ /ŋ/ sing /sɪŋ/ # /r/ red /red/ /j/ yes /jes/ /w/ wet /wet/ # /l/ light /laɪt/ cool /kuːl/ # /ts/ cats /kæts/ /dz/ beds /bedz/ /tr/ tree /triː/ /dr/ dream /driːm/ /l/ 有 2 个发音:clear l(示例:like)、dark l(示例:school) ↩︎

2025/2/26
articleCard.readMore

KK 音标、DJ 音标、IPA 音标对照表

本文内容摘录自KK音标 - 维基百科,自由的百科全书。 # KK DJ IPA 单字示例 [i] [iː] [iː] seat [ɪ] [ɪ] [ɪ] sit [e] [eɪ] [eɪ] pain [ɛ] [e] [e] head [æ] [æ] [æ] fat [ɑ] [ɑː] [ɑ] hot [o] [əʊ] [əʊ] nose [ɔ] [ɔː] [ɔː] four [ɔ] [ɔ] [ɒ] dog [u] [uː] [uː] too [ᴜ] [ʊ] [ʊ] put [ʌ] [ʌ] [ʌ] sun [ə] [ə] [ə] again [ɪr] [ɪə] [ɪə] rear [ɚ] [ə] [ə˞] brother [ɝ] [ɜ] [ɜ˞] bird # KK DJ IPA 单字示例 [aɪ] [aɪ] [aɪ] pie [aᴜ] [aʊ] [aʊ] house [ɔɪ] [ɔɪ] [ɔɪ] coin # KK DJ IPA 单字示例 [p] [p] [p] pet [t] [t] [t] ten [k] [k] [k] key [f] [f] [f] fat [s] [s] [s] sing [θ] [θ] [θ] thank [ʃ] [ʃ] [ʃ] short [tʃ] [tʃ] [tʃ] chair [h] [h] [h] ha # KK DJ IPA 单字示例 [b] [b] [b] book [d] [d] [d] desk [g] [g] [ɡ] get [v] [v] [v] vest [z] [z] [z] zoo [ð] [ð] [ð] this [ʒ] [ʒ] [ʒ] measure [dʒ] [dʒ] [dʒ] john [m] [m] [m] mom [n] [n] [n] nose [ŋ] [ŋ] [ŋ] sing [l] [l] [l] long [r] [r] [r] red [j] [j] [j] yes [w] [w] [w] we

2025/2/23
articleCard.readMore

排查手机卡顿

最近听朋友说小米 13 卡顿,我感觉不应该啊,这手机处理器是骁龙 8 第二代(2022年末的旗舰处理器)。 用安兔兔 v10.4.4 测试性能,才 134 万分,排行榜上面小米 13 的分数是 155 万,相差 21 万。嗯,这个结果不对劲。 看了内存使用,内存是 12G + 4G,可用只有 3.1G。但是手机也就运行了两个微信。剩余内存太少了吧。 看了下开机时间,居然开了 142 天,震惊!居然有人开手机那么久不重启。 把手机升级到最新的系统,再测一遍性能。原来 134 万,这次 160 万,比参考值多 5 万。这次正常了。操作也不觉得卡。 我猜是卡顿是因为手机开太久了,系统出现内存泄漏,性能下降。嘱咐朋友至少每周重启手机,要安装更新(这也是重启的机会)。 朋友有时候手机快用完电才去充,这样容易损耗电池。我嘱咐他多充电,让手机保持高电量。充电时尽量不要用手机,因为充电手机会发热,这时用手机就更热了,发热会降低电池寿命。 总结一下我的建议: 更新系统 每周重启,或者卡顿就重启,也可以设置每天定时开关机 多充电,不要到 20% 这样低电量才充 以后买新手机先用安兔兔测试性能,和参考值相差几万应该是正常的 手机过了一个星期都没卡,问题算是解决了。期间朋友每天重启手机,一开始手动重启,后来设置了每天自动关开机。

2025/2/21
articleCard.readMore

痛失小米 9 SE

小米 9 SE 是我的上上台手机,我换手机之后就没用过了。最近拿出来,发现居然能安装最新的 LineageOS 22.1(Android 15)。我一直感觉在 Android 用 root 权限是比较危险的,所以没用过。刚好这台空闲的手机可以让我测试,测试好一些应用或者模块,我就在一加 Ace 3 上面用。我还很喜欢小米 9 SE 小巧的尺寸,现在已经很少可以单手使用的小尺寸手机了。 这台小米 9 SE 有两个比较严重的问题:烧屏(屏幕泛黄、有残影)、电池损耗严重(出门必须带移动电源)。感觉换屏幕太麻烦,就算了。电池倒是可以换个新的。花 69 元人民币买了块诺希牌电池,自己安装。 客服发的安装视频里的工具和实际的工具略有不同。视频里用胶带贴后盖,我拿到的是胶水。视频看了一遍,感觉自己能搞定。 第一步是打开后盖。关机,用吹风机加热后盖,用吸盘贴住后盖底部,用三角拆机片抠开边缘。工具要放远点或者装起来,不然吹风机会吹走工具。 第二步是拆螺丝。按顺序拆下 10 颗螺丝,在纸上画图,用 1~10 的数字标记位置,把螺丝放在纸上。挑起电池排线。 第三步是取电池。加热电池,很不幸把螺丝吹开了,发现有 2 颗螺丝是短的,不知道装的时候该装哪个位置。拉出电池底下延伸出来的胶条,很难拔,还拔断了,胶条还残留在电池底部。接下来用工具用力撬起电池(错误操作),中途还太大力刺伤手指了,疼! 差不多撬起来的时候,电池有点变形了,再撬电池就破了。电池冒烟,我脑子还没反应过来,手就把手机丢到地上了。电池接着就着火和冒烟,燃烧完后电池很胀,屏幕被加热到出现一个白色的实心圆圈,烟的气味很臭很刺鼻,过了一晚才闻不到。幸好人和房子都没事。最后把电池和主板装到袋子,贴上「锂电池」的纸,放在有害垃圾垃圾桶旁边了。附近的人似乎不分类丢垃圾,所以我就把电池直接放垃圾桶旁边,希望回收垃圾的人能看到。 换电池失误的后果好严重,主板都烫坏了,以后还是去售后中心换电池吧。真怀念以前的手机,关机打开后盖就直接换电池了。

2025/2/20
articleCard.readMore

将一加 Ace 3 从 PixelOS 14 升级到 PixelOS 15

现在 PixelOS 15 发布了,我就打算从 PixelOS 14 升级上去,但是事情没那么简单。因为 PixelOS 15 要用到 ColorOS 15 的固件,所以不能直接升级。要安装 ColorOS 14,升级到 ColorOS 15(15.0.0.200 或者以上的版本),在 ColorOS 的更新器再次安装 ColorOS 15 以确保两个系统槽位(slot)都是 ColorOS 15。安装 ColorOS 14 的时候会清空用户数据,所以要先备份应用和文件,最后再恢复。 操作有风险,推荐在有条件去售后中心的时候操作,失败了就去售后直接安装 ColorOS 15 吧。 # PJE110domestic_11_14.0.0.317CN01_2024012904340000.zip(如果无法下载就先登录谷歌账号) ColorOS PJE110_15.0.0.500(CN01) C.32 全量包(里面的链接用浏览器打开失败,可以用 aria2 或者 Aria2App 下载) 1.3.zip 和 prog_firehose_ddr.zip(在这里下载:How To Guide - [12R/Ace 3] EDL DownloadTool to restore your device to OxygenOS/ColorOS | XDA Forums) ColorOS PJE110_14.0.0.800(CN01) A.67 全量包(里面的链接用浏览器打开失败,可以用 aria2 或者 Aria2App 下载) Fastboot Firmware Flasher(需要 Windows 10 / 11) # 我用 DataBackup 来备份应用与它们的数据、文件。 应用 DCIM Pictures Documents DataBackup 需要 root 权限,我用最新构建的 APatch(使用文档,注意最新构建版是个 .zip 文件,需要解压之后安装里面的 .apk),你也可以用其他 root 方案。 备份完删掉一些应用再恢复,看看能不能行。没问题就把数据复制到电脑。 我对微信没有信心,所以将微信聊天记录额外备份到电脑。 有些东西 DataBackup 无法备份,只能自己截图或者用文字记下来。无法备份的东西有: 系统设置(WIFI 密码、星标联系人、闹钟、谷歌账户等) APatch 设置和模块(应该也能备份吧,但总感觉不太对劲) # 退出谷歌账号,删除锁屏密码。 # 参考 How To Guide - [12R/Ace 3] EDL DownloadTool to restore your device to OxygenOS/ColorOS | XDA Forums,用 9008/EDL 模式安装 ColorOS 14。 在 Download OnePlus 12R/Ace 3 EDL Unbrick Firmware/ROM - DroidWin 下载 EDL 刷机包(PJE110domestic_11_14.0.0.317CN01_2024012904340000.zip),登录谷歌账户才行,不然提示下载人数太多。 解压 zip 包。 将 xda 帖子的 prog_firehose_ddr.elf 放到 系统包/IMAGES/,覆盖掉里面的 prog_firehose_ddr.elf。 打开 9008驱动.exe,安装。 打开报错安装我,提示已安装这个产品的另一个版本。 打开刷机工具1.3。 区域选择非欧洲,用户名、密码、验证码都输入 1,登录。 将系统包的文件夹拖拽进去。 保持默认选项,点击ok,点击开始。 手机按住两个音量键和电源键,刷机工具显示连接就松手。 显示 firehose 协议执行失败,好像是因为我前面还没关闭 fastboot firmware flasher,关闭它之后再来用刷机工具1.3就好了。 6 分钟后完成刷机,再等一段时间,ColorOS 14 开机成功。 # ColorOS 14 开机成功,进入设置引导界面,增强服务这里关闭「自动下载」和「夜间自动更新」,后面的能跳过就点跳过。 目前版本信息是 PJE110_14.0.0.317(CN01)。 将手机插到电脑,复制 ColorOS PJE110_15.0.0.500 刷机包到手机的 Download 文件夹。 开启开发者模式:打开设置-关于本机-版本信息-快速多次点击版本号。 开启飞行模式(关闭数据和 WIFI)。 打开设置-应用-应用管理-右上角的三个点-显示系统应用-搜索软件更新-储存占用-清除数据。 打开设置-关于本机-ColorOS-右上角的三个点-本地安装-选择前面从电脑放进去的 ColorOS 15 刷机包-立即解压-立刻安装。 安装完后重启到 ColorOS 15。 友情提示:升级到 ColorOS 15 之后,原来的免授权 EDL 刷机工具会失效,用 EDL 工具的新方法:Fix Sahara Communication/Protocol Failed Error in Oppo Flash Tool - DroidWin。 # 现在进入了设置引导界面,关闭「自动下载」和「夜间自动更新」。现在版本信息是 PJE110_15.0.0.500(CN01)。 像前面一样,在设置里面使用本地安装,现在是第 2 次安装 ColorOS 15,安装完选立即重启。 # 现在准备工作都做好了,按照 PixelOS 官方教程 做就行了。 手机关机,按住音量下键和电源键开机进入 fastboot,连接电脑。 1 2 3 4 5 fastboot flash boot boot-aston_20250121_1747.img fastboot flash init_boot init_boot-aston_20250121_1747.img fastboot flash vendor_boot vendor_boot-aston_20250121_1747.img fastboot flash dtbo dtbo-aston_20250121_1747.img fastboot flash recovery recovery-aston_20250121_1747.img 按手机音量下键,直到显示 Recovery mode,按下电源键确认。现在进入 PixelOS 的 recovery 了。 在手机选择 Apply update - Apply from ADB。 1 adb sideload PixelOS_aston-15.0-20250121-1747.zip 手机询问「Do you want to reboot to recovery now?」(是否重启到 recovery),选择 No。 选择 Factory reset - Format data/factory reset - Format data。 点左上角的左箭头返回,选择 Reboot system now。 简单设置一下: Refresh rate 120 Hz (Adaptive) Tap to wake Tap to sleep Display size and text - Display size(调大 1 档) Network traffic indicator # 安装 APatch,修补 boot.img,刷入后手机开机后卡死,触屏和按键没反应。头疼!按住音量上键和电源键强制重启,屏幕熄灭时马上松手并按住音量下键,进入 fastboot。刷入 PixelOS 的 boot.img。 1 2 fastboot flash boot boot-aston_20250121_1747.img fastboot reboot KernelSU 也试了下,刷入修补的 init_boot.img 后并不能获取 root 权限。最后只能用 Magisk 了。 把前面备份的数据从电脑复制到手机(里面有 DataBackup),安装 DataBackup 后恢复应用和数据。 有些应用要重新登录或者设置: Bitwarden Outlook 支付宝 欧路词典 不需要重新登录或者设置的应用: 微信 KDE Connect 闪退的应用: Hail GKD 其他设置自己手动处理。 连接 WIFI,登录谷歌账号。 同步 outlook 联系人 设置星标联系人 设置闹钟 克隆应用的功能没了,只好装个 Insular 安装 root 模块 # Magisk 真的太容易被检测到了,云闪付、支付宝、微信里面都没有人脸支付、指纹支付的选项,云闪付直接提示处于 root 环境。之前用 APatch,支付宝是可以人脸支付的。真是头疼,只能先不用 root 了,支付宝又能用人脸支付了。 # PixelOS 的维护者 inferno0230 提供了支持 KernelSU 的内核。我试了 OP12R-v5.15.175-20250119-0950.zip,在 PixelOS Recovery 里选 Apply update - Apply from ADB,在电脑执行 adb sideload OP12R-v5.15.175-20250119-0950.zip 就安装成功了。我把 KernelSU 管理器安装到 private space,用支付宝人脸识别正常,云闪付也没有提示 root 环境。 # 推荐方法: 下载最新的 KernelSU 内核。 在设置更新系统,安装完按住电源下键,重启。 按音量键选择 recovery,按电源键确认,进入 recovery。 Apply update - Apply from ADB / Choose from disk1 - Yes - Reboot system now。 不太推荐的方法(手误跨版本升级 PixelOS 可能会出问题,比如 PixelOS 15 升级到 PixelOS 16): 下载 KernelSU 内核和 PixelOS 系统 重启到 recovery 安装 PixelOS,重启到 recovery,此时系统槽位(slot)变化 安装 KernelSU 内核 重启 # 删除电脑的备份文件、刷机包、刷机工具、微信记录。 文章到这里就结束了,下面是安装 ColosOS 14 的失败尝试,不知道是我操作不当还是工具有问题。 2025-02-20 更新:今天看到用 fastboot 安装原厂系统的教程(How To Guide - Flashing stock firmware on 12r/Ace 3 from fastboot. | XDA Forums),可能我下面失败的原因是没装好驱动,手机在 fastbootd 模式时未被电脑检测到。 Download the usb drivers, extract them and install “android_winusb.inf” by right clicking on it then click install. Install them even if your device is detected in fastboot mode because further in the guide the phone will go in fastbootD mode and your computer might not detect the phone in that mode. # 手机关机,按住电源键和音量下键开机,手机震动后松手,进入 fastboot 模式。将手机插到电脑 USB 口。 打开 Fastboot Firmware Flasher。 选择 [7] FIRMWARE UNPACKER,解开 ColorOS 14。 返回主菜单,选择 [3] FLASH ROM。 电脑显示 Rebooting into fastboot,但是手机进了 fastbootd,电脑显示「waiting for any device」。手机可以选择清除数据、重启、关机,我选了选择关机,结果就反复启动了。 可以把内核放到 U 盘,从 U 盘安装,这样就不需要用电脑。注意:PixelOS recovery 无法读取多分区的 U 盘。 ↩︎

2025/2/13
articleCard.readMore

用文本文件制作 Anki 牌组

Anki 是开源的记忆软件。我们可以用文本文件制作牌组(一组需要记忆的内容),文本文件更易于修改。 将下面文本保存为 deck.txt,然后用文本编辑器编辑。 1 2 3 4 5 #separator:Pipe #html:true hi|你好 why|为何 two lines|第 1 行<br>第 2 行 此文本对应的导出格式是「Cards in Plain Text(.txt)」。 第 1 行的 separator(分隔符)用于区分正面和反面,可以用 Comma(,)、Semicolon(;)、Tab( )、Space( )、Pipe(|)、Colon(:),用名称(例如:Pipe)和符号(例如:|)都可以。我推荐用 |,它很少在卡片里用到,而且可以用键盘直接输入。 第 2 行表示可以使用 HTML 代码。比如:<br> 表示换行。 第 3 行开始就是卡片,一行就是一张卡,分隔符左边是卡片正面,分隔符右边是卡片反面。 在 Anki 创建牌组,将 deck.txt 导入到这个牌组。如果你想制作翻转卡片(反面->正面),导入时 Note Type 选择「Basic and (reversed) card」,这样牌组会同时存在基础卡片(正面->反面)和翻转卡片。 相关资料:Text Files - Anki Manual

2025/1/30
articleCard.readMore

在闲鱼遭遇到手后砍价,最后拿回货款

为保护隐私,本故事略有改编。 # 我在闲鱼卖一台五六年前发售的手机,定价 200 元人民币,原价 2999 元。这台手机可以正常使用,屏幕有一处明显划痕,边框掉漆。 放了几天,有个人猛砍价1到 120 元,我说 180 元他就不回了。 后来又有个人问了,这个人一开始就让我感觉不爽。她的名字类似于「闭嘴吧你」,一副不好沟通的模样,芝麻信用还未授权。 买家说话吞吞吐吐,沟通起来很浪费时间。 买家:你好 我:你好,想了解一下这台手机吗? 买家:是的 我内心:喂,你有话快说,非要我说一句你就说一句吗! 买家开始问有没有换过屏幕和电池,是不是自用。我说原装自用。买家叫我拍边框,拍了她就挑剔有磕碰,又说几年前手机电池不行,换电池都要几十块,以这些为由要求降价。这时我就开始感觉恶心,二手手机本来就有耗损,还按照新机那种标准挑剔,新机至于卖 200 吗? 买家问钢化膜、手机壳、充电器。我都在商品页面写清楚只有手机跟手机壳了。买家还嫌手机壳变色。几年前的手机壳你想要多好,有送都不错了。买家问有没有划痕,我都在商品页面说了在哪个位置有一处明显划痕,她又要我拍照。 充电器我说用 USB Type-C 就行了,其他品牌的充电器也可以的。买家以只有 iPhone 为由(iPhone 15 之前的 iPhone 不使用 Type-C 接口),让我送数据线。为了促成交易,我也送了一条本来在用的,重新买又得十多块,气死。 买家问有没有账号、会不会重启,最后她砍价到 160 元,并且收到马上确认收货(买家确认收货,卖家才会收到货款)。我内心的最低价格是 180 元,她砍那么多我是很不爽的,看她说马上确认收货就算了吧。 下单后她说地址错了。我不知道这是什么套路。让她取消订单,重新上架让她买。 # 发货后买家这个贱人又开始挑剔了,想看购买凭证。我连包装盒都没了,哪来的购买凭证。一般人也不会问这个,这台手机没什么造假价值,又不是奢侈品。 到货后买家并没有爽快得确认收货,从这时开始她越来越恶心了。她说手机缝隙不一致,怀疑拆过机,一边缝隙大,似乎夹了纸片。我也不确定,但之前用手机的时候是没问题的,我就说不用就放着了。于是买家又换另一个理由,说摄像头进灰了影响拍照,又装可怜说贴膜、手机壳、充电头也要钱,希望我优惠点(到手后砍价)。这些配件要钱关我屁事,而且她那么吝啬肯定不会买配件。啊,气死我了!我说摄像头进灰是二手机正常损耗。我手头上刚好有台摄像头进灰的手机,前置摄像头和后置摄像头都进灰了,但是拍照没有明显问题。 过了一天,买家说去手机店清灰要 20 元,问我给她 20 元还是退货2。我说已经最优惠了。她接下来一直以进灰为由缠着我,我就一直说已经最优惠了,后面不想回复了等到货后 3 天自动确认收货。结果这个家伙在最后一天申请了退货,理由是质量问题/功能异常,附上前摄像头的照片,确实有灰尘。最后没收货真是气死我了。 我无法接受退货,因为: 不能容忍她讹人这样错误的行为。 质量问题退货要卖家(我)给运费。 我前面的交流让我觉得她品德低下,怕她弄坏手机再寄回来,真的有人得不到就毁掉。 我不想留下质量问题退货的记录。 # 我拒绝了退货申请,理由是:问题不存在,补充的文字和截图表示买家有到手刀(到手后砍价)行为。我点击维权之后就进到闲鱼小法庭了。闲鱼小法庭就是解决买家卖家纠纷的方式,由 17 位陪审员(闲鱼用户)投票,17 票 9 胜制,票差小于 4 票时可以申诉。陪审员可以查看双方聊天记录。小法庭有两个环节:前 24 小时是双方举证,发起维权者先发言 1 次,然后开始计时,双方可以发言 5 次;后 24 小时是评审员投票。在我这个例子,如果我赢了就马上到账,如果买家赢了我就必须接受退货。 老实说,第一次上小法庭还是蛮紧张的,要是输了就很难过。发言太多了,我就简单总结一下。 买家的发言: 摄像头进灰影响拍照(附上前摄像头照片,水印表面是用 Android 手机拍的)。 卖家不说明摄像头有灰尘、敷衍了事、不回信息。 急起来说气话,说卖家强买强卖和土匪(拜托,是你自己买又不是我逼你买的)、说用多台手机不行吗。 卖家未标明售出不退。 卖家(我)的发言: 摄像头进灰是手机使用的正常损耗,我之前自拍和打视频电话都没问题,我已经提供了最优惠的价格。 买家买前过度挑剔,也没有表面很在意摄像头灰尘。 买家到手后用模糊的语言砍价(说缝隙大又不提供图片,说摄像头进灰在聊天时也未提供图片),心虚才不会提供照片证明观点。 买家承诺直接确认收货,买后到手刀,这是不诚信。 买家说自己用 iPhone 没 Type-C 数据线,但被我发现他拍照用了 Android 手机,所以他有 Type-C 数据线。买家骗了我一条数据线,这是不诚信。 差不多晚上 12 点的时候开始投票,第二天买家已经取消了退货申请,大概是自知理亏。买家拖 20 小时后自动确认收货,我收到钱了,太好了! # 现在回想起来,买家的手段不算很高明,只是我没经验而且想快点卖出手机就中招了。 下面总结一下甄别坏买家和避免纠纷的技巧。 # 有以下特征的买家可能是坏买家: 吞吞吐吐(可能没有恶意,但和这样的人聊天很浪费时间) 挑剔,尤其是不合理的挑剔(电池损耗) 用模糊的表达而不是提供证据 表现得很在意问题但只要求砍价(一般人会选择退货) 没有芝麻信用或者买家芝麻信用优秀以下 差评多 新用户 # 拍 360 度视频/图片 拍装箱视频 用验货宝(闲鱼的验货服务) 声明售出后非质量问题不退 像 200 元砍到 120 元这种大比例砍价叫做屠龙刀。 ↩︎ 如果不想和买家纠缠,一定要让其确认收货后才发钱给他。 ↩︎

2025/1/1
articleCard.readMore

了解与使用 Android 的 root 权限

root 权限 # root 是 Android 系统的最高权限。Android 系统就像房子。没有 root 的时候用户就是租客,只有使用权,不能随便改动房子。有 root 权限的时候,用户就是房东,有所有权,可以随便改动房子(修改系统)、丢掉原有的家具(卸载系统应用)。 总之,有了 root 权限之后我们就可以完全掌控 Android 系统了。 # 获取 root 的前提条件是解锁引导程序(bootloader),解锁了引导程序才能安装 init_boot.img 和 boot.img。 init_boot.img 和 boot.img 是启动系统需要用到的文件,推荐先备份好它们。修补其中一个并安装后就能获取 root 权限。最后使用 root 管理器来管理 root 权限。 # 目前有三个开源的 root 方案: Magisk(使用文档、源代码) KernelSU(使用文档、源代码) APatch(使用文档、源代码) Magisk 是最经典的 root 方案,教程和资源最多。缺点是容易被应用检测到,比如:中国农业银行应用检测到 root 会退出。用额外的模块才能隐藏 root。 KernelSU 是内核级 root 方案,不需要刻意隐藏 root,被授权的应用才能感知到 root。App Profile 功能可以授予应用部分权限,比如:只允许应用使用 adb 权限。 APatch 也是内核级 root 方案,KernelSU 是内核级 root 方案,不需要刻意隐藏 root,被授权的应用才能感知到 root。需要设置密码。 我的推荐:KernelSU > APatch > Magisk(> 表示优于)。KernelSU 排第一是因为它不易被检测,而且可以授予应用部分权限。Magisk 排最后是因为容易被检测。 # root 有两种使用方法。一是管理器授权给应用,二是在管理器安装 root 模块(module)。比如:授权给 Neo Backup 就可以备份应用。安装 BCR 模块之后可以自动录制通话。 root 权限可以很危险,比如用来清除手机数据或者弄坏系统。请勿授权给来源不明的应用,也不要安装来源不明的模块。尽量选择开源、知名的应用和模块。 # 模块是使用 root 管理器安装的应用。 Zygisk 是修改系统和应用行为的模块,供其他模块使用。Magisk 内置 Zygisk。KernelSU 和 APatch 没有内置 Zygisk,但是可以安装独立版 Zygisk。 以下是独立版 Zygisk: ReZygisk(开源) ZygiskNext(最新版本闭源) Xposed 是修改系统和应用行为的模块,供其他模块使用。Xposed 已经停止更新,其继任者 LSPosed 也停止更新。目前还在更新的 LSPosed 修改版为 JingMatrix/LSPosed。注意 LSPosed 依赖于 Zygisk,要先安装 Zygisk 才能用 LSPosed。 安装 Zygisk 和 LSPosed 后,root 特征更明显,root 更容易被检测到。 # 银行应用和游戏检测到 root 后可能会拒绝运行,此时要隐藏 root。 隐藏 root 的模块: Zygisk-Assistant(开源) Shamiko(闭源。APatch 不支持 Shamiko。) Cherish Peekaboo(闭源,APatch 专用,在这个帖子的 Attachments 可以下载。) Android 系统允许应用获取所有应用的名字。有些应用发现系统有 root 管理器或者使用 root 的应用,就认为系统有 root 权限而拒绝运行。我们可以使用 Hide My Applist 或者 HMAL 来隐藏应用名称,从而躲过检测。 隐藏完 root 后可以使用root 检测应用查看效果。如果你用的应用没检测出 root,就不要纠结 root 检测应用的结果。 # 一些银行应用会检测 Play Integrity(设备完整性,等级包适 BASIC、DEVICE、STRONG),手机解锁引导程序后 Play Integrity 等级下降,导致银行应用拒绝运行或者隐藏部分功能(比如指纹支付)。可以使用 Play Integrity Fix 和 TrickyStore 来修复 Play Integrity。 # 我一般用 KernelSU 或者 APatch。 用到 root 的应用有: App Manager DataBackup Material Files MMRL Shizuku App Ops Droid-ify GKD Hail Obtainium aShell You 模块有: BCR root 的功能远不止这些,推荐你看 GitHub - fynks/awesome-android-root: A comprehensive and up-to-date list of latest Android root apps that require or utilize root privileges, rooting guides, tips, tricks and tools。

2024/12/23
articleCard.readMore

推荐可以刷机的一加 Ace 3

上个月买了可以刷机1的一加 Ace 32。一加 Ace 3 的性能不错,处理器是骁龙 8 二代(2022 年末的旗舰处理器),目前在骁龙处理器中仅次于骁龙 8 三代和骁龙 8 至尊版。喜欢刷机的读者可以考虑这台手机。 相关链接: 一加 Ace 3 参数规格 OnePlus Ace 3 - Full phone specifications OnePlus 12R / OnePlus Ace 3 | XDA Forums 刷机指安装操作系统。 ↩︎ 一加 Ace 3 的国际版为 OnePlus 12R。 ↩︎

2024/12/15
articleCard.readMore

小米已退烧

小米一开始的口号是为发烧(友)而生,现在新的解锁 bootloader 政策让我感觉小米退烧了。 原本小米解锁 bootloader 的条件是等待 168 小时(7 天)。小米推出 HyperOS 后中国大陆的型号解锁 bootloader 非常难,需要小米社区 5 级,还要考试1。 这个解锁政策真是让我大跌眼镜,根本是刁难用户。真搞不明白小米公司怎么想的。如果嫌用户解锁后弄坏手机要去售后,那可以在用户解锁 bootloader 后取消售后。 新解锁政策还有一个恶心的点:只针对中国大陆的设备。凭什么陆版手机解锁就那么难,国际版手机解锁就和以前一样2。 新解锁政策大大影响了第三方 ROM 的开发。本小米老用户感到伤心、失望、生气。买陆版小米手机刷机的日子可能一去不复返了。 HyperSploit 和 Xiaomi-HyperOS-BootLoader-Bypass 可以绕过 HyperOS 的解锁限制,推荐使用前者。 ↩︎ 国际版手机解锁也没那么容易了,我在 PixelOS Chat 看到有人申请解锁时提示额度已满(https://t.me/pixeloschat/466581)。 ↩︎

2024/12/8
articleCard.readMore

一加 Ace 3 刷机前的准备与安装 PixelOS 的过程

PixelOS 升级流程:将一加 Ace 3 从 PixelOS 14 升级到 PixelOS 15。 # 本文的操作可能会过时,建议参考文末的文章。 拿到手机要马上关闭自动更新,避免更新到不合适刷机的版本。 解锁 bootloader 重启后马上关掉自动更新。 解锁 bootloader 时会清除数据。如果确定要刷机,建议买到手机马上解锁,后面拿到 root 权限可以用 Neo Backup 备份应用数据。 # 刷机:安装操作系统 ROM:操作系统。ROM 本义是可读存储器(read-only memory),在刷机的语境下是(安装于 ROM 的)操作系统的意思。 bootloader:引导程序,需要先解锁它才能安装其他操作系统 root:最高权限 ocdt.img:每台一加手机特有的分区 persist.img:每台手机特有的分区 # 先看这篇恢复系统的教程:How To Guide - [12R/Ace 3] EDL DownloadTool to restore your device to OxygenOS/ColorOS | XDA Forums,最好用不上啦。 # 测试硬件功能,参考 charter/device-support-requirements.md at main · LineageOS/charter。 确定硬件没问题后,如果刷机后有问题就是 ROM 有问题。 扬声器、听筒 WIFI 通话 USB 蓝牙 前置摄像头(拍照、录像) 后置摄像头(0.6/1/2/5 倍数,拍照、录像) 指纹 NFC 红外线(遥控) 定位 陀螺仪(指南针) 距离传感器(通话时会熄屏) 光传感器(自动亮度) 网络(只测了 5G) # 记录版本信息,可能以后有用。打开设置->关于手机->版本信息。 1 2 3 4 5 6 7 8 版本号 PJE110_14.0.0.813(CN01U140P02) 基带版本 Q_V1_P14,Q_V1_P14 内核版本 5.15.123-android-13-8-00766-gf04dea8b48fa SOTA 版本号 U140P02(BRB1CN01) # 在电脑安装 adb 和 fastboot,参看 Using ADB and fastboot | LineageOS Wiki。 解锁时会清除数据。如果确定要刷机,建议买到手机马上解锁,后面拿到 root 权限可以用 Neo Backup 备份应用数据。 打开设置->关于手机->版本信息,快速多次点击版本号,开启开发者模式。 返回设置,打开系统与更新->开发者选项,开启 OEM 解锁和 USB 调试。 手机通过数据线插到电脑 USB 口。 1 2 3 4 adb devices # 手机按允许调试 adb reboot bootloader # 进入 fastboot 模式 fastboot devices # 应该会看到编号 fastboot flashing unlock # 解锁 bootloader,用音量键选择 UNLOCK THE BOOTLOADER,按电源键确认 现在手机重置了,开机后跳过可以跳过的设置,进入桌面。打开设置,搜索「更新」,打开「自动更新设置」,关闭自动下载和夜间自动更新。 # Oxygen Updater 不能下载一加 Ace 3 的 ROM,所以从大侠阿木的网站下载当前版本的 ROM,也就是 PJE110_14.0.0.813。 解压文件,获得 payload.bin。 安装 payload-dumper-go。 1 2 # Arch Linux 的安装方法 paru -S payload-dumper-go-bin 解压 payload.bin。 1 payload-dumper-go payload.bin 进入解压目录,将 init_boot.img 传到手机。 1 adb push init_boot.img /sdcard/Download/ 在电脑下载 Magisk,通过 adb 安装到手机。 1 adb install app-release.apk # 在手机同意安装 在手机打开 Magisk,点击「Magisk 安装->选择并修复一个文件」,选择 init_boot.img,点击「开始」。在文件管理将修补好的文件重命名为 magisk_patched.img。 将 magisk_patched.img 复制到电脑。 1 adb pull /sdcard/Download/magisk_patched.img 获取 root 权限。 1 2 3 adb reboot bootloader fastboot flash init_boot magisk_patched.img fastboot reboot # 每台一加手机的 ocdt.img 和 persist.img 都是独一无二的,所以先要备份下来。 1 2 3 4 5 6 adb shell su # 在手机授权 dd if=/dev/block/bootdevice/by-name/ocdt of=/sdcard/Download/ocdt.img dd if=/dev/block/bootdevice/by-name/persist of=/sdcard/Download/persist.img exit exit 现在 ocdt.img 和 persist.img 都在手机的 Download 文件夹,将它们复制到电脑。 1 2 adb pull /sdcard/Download/ocdt.img adb pull /sdcard/Download/persist.img 把前面记录的版本信息保存成文本文件,和这两个 .img 文件一起备份到网盘。 # 参考以下资料安装 Pixel OS。 PixelOS - aston(点击页面的 Download 可以下载需要的文件) Development - [12R/ACE3][ROM][14][OFFICIAL] PixelOS [AOSP][19/10/24] | XDA Forums 我的安装过程有错误操作,为了避免误导读者,就删掉了。如果你真的想看,请点击这里。 Apply from ADB。 ``` adb sideload PixelOS_aston-14.0-20241018-1605.zip ``` 现在屏幕显示 `Active slot: b` 和 `Do you want to reboot to recovery now?`,选择 `Yes`。 现在屏幕显示 `Active slot: a`,选择 Apply update -> Apply from ADB,再次安装 PixelOS(文档写要安装两次,这里是错误操作,应该是进入系统后再次安装)。 ```shell adb sideload PixelOS_aston-14.0-20241018-1605.zip ``` 这次报错了,先不管。 选择 Factory reset -> Format data/factory reset -> Format data,返回,选择 Reboot system now。可以开机。 开机连接 WIFI 后等了有两三分钟,显示 Slow connection,选择左边的 Set up offline。字体有点小,在设置里调大 Display size。 原系统在 https://resolution-viewer.cyrusyip.org/ 看到的缩放值好像是 350% 下拉通知栏,点击「Charging this device via USB」,选择 File Transfer。在电脑把 `PixelOS_aston-14.0-20241018-1605.zip` 复制到 Download 文件夹。 在手机打开 Settings -> System -> System updates -> Local update,选择刚刚的 `.zip`文件,点击 INSTALL,完成后点 Reboot,重启成功。 再重启一次,没事,应该算成功安装 PixelOS 了。 --> 系统自带谷歌服务,用 YASNAC 测试 SafetyNet,Basic integrity 显示 pass。 # 参考前面的章节。既然在原装系统没事,我这次就懒得测了。 # How To Guide - How to root OnePlus 12R, a complete guide | XDA Forums Installation | Magisk How to Backup and Flash ocdt and persist partition on OnePlus - DroidWin Backup ocdt.img or You Might Lose Fastboot Mode [OnePlus] - YouTube Development - [12R/ACE3][ROM][14][OFFICIAL] PixelOS [AOSP][19/10/24] | XDA Forums PixelOS - aston How To Guide - [12R/Ace 3] EDL DownloadTool to restore your device to OxygenOS/ColorOS | XDA Forums

2024/12/5
articleCard.readMore

OPPO / 一加 / ColorOS 的 Google Play 安装教程

开启谷歌服务:打开设置,搜索「google」,点击「Google 设置」,开启「Google 移动服务」。 安装 Google Play:打开应用商店,搜索「google play」,升级「谷歌应用市场」。升级完后桌面会出现「Play 商店」。 测试机型:一加 OnePlus Ace 3(ColorOS 14)、OPPO Reno12(ColorOS 14)。

2024/11/15
articleCard.readMore

概念解析:物理像素、逻辑像素、CSS 像素、物理分辨率、逻辑分辨率

物理(physical)表示实际的值,逻辑(logical)表示经过缩放的值。 # 像素(pixel)是显示器的基本单位,一个像素显示一种颜色。为了和逻辑像素(logical pixel)区分,像素(pixel)又称物理像素(physical pixel)。 # 逻辑像素(logical pixel),亦称 CSS 像素(CSS pixel),是经过操作系统缩放的像素。CSS 的 px 就是 CSS 像素。 # 物理分辨率(physical resolution)表示像素的数量。1920×1080 分辨率就表示显示器水平方向有 1920 个像素,垂直方向有 1080 个像素,共 2073600 个像素。尺寸相同时,显示器分辨率越高,显示效果就越精细。 # 逻辑分辨率(logical resolution)是经过系统缩放的分辨率。 我用 1920×1080 分辨率,27 英寸的显示器,文字看得清楚。假如我换成同尺寸 3840×2160 的显示器,此时显示器像素数是前者的 4 倍,可以容纳更多的文字,文字会变得小得看不清。在浏览器按几下 Ctrl - 调节缩放也可以看到过小的文字。 在系统设置 200% 缩放后,分辨率就变成了 (3840/2)×(2160/2),也就是 1920×1080,此时文字大小又正常了。3840×2160 是物理分辨率,1920×1080是逻辑分辨率。 # 以 2560×1440 物理分辨率,200% 缩放的显示器为例,展示相关 Web API 的用法。 1 2 3 4 5 6 7 8 9 10 // 逻辑宽度 console.log(window.screen.width) // 1280 // 逻辑高度 console.log(window.screen.height) // 720 // 缩放(物理高度/逻辑高度) console.log(window.devicePixelRatio) // 2 // 物理宽度,需要借助 devicePixelRatio 来计算 console.log(window.screen.width*window.devicePixelRatio) // 2560 // 物理高度,需要借助 devicePixelRatio 来计算 console.log(window.screen.height*window.devicePixelRatio) // 1440 # 我写了个查看物理分辨率、逻辑分辨率和视口大小的网站,欢迎使用。 网站链接:https://resolution-viewer.cyrusyip.org/ 源代码:https://github.com/CyrusYip/resolution-viewer

2024/11/2
articleCard.readMore

jQuery 使用笔记

jQuery 是一个经典的 JavaScript 库,其功能为修改 HTML 元素、处理事件、制作动画、发送请求(Ajax)。jQuery 首次发布于 2006 年 8 月 26 日,现在(2024 年)已经 18 岁了。截止于 2024 年 10 月 23 日,有 75.8% 的网站使用了 jQuery1。 虽然 jQuery 的使用率高,但新项目没必要用 jQuery,原生 JavaScript 已经可以实现 jQuery 的操作,参看 You Might Not Need jQuery 和 You-Dont-Need-jQuery。维护老项目时可能会用到 jQuery。 jQuery 的引入方法很多,我在本文采用 CDN 引入。 1 <script src="https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js" integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous"></script> 下面介绍一些常见用法。 # jQuery 使用 CSS 选择器获取元素。 1 2 3 $(document) // 获取整个文档 $("#id1") // 获取 id 为 id1 的元素 $(".class1") // 获取 class 为 class1 的元素 # 1 2 <!-- HTML 示例 --> <div id="container"><p>Container</p></div> 1 2 3 4 $("#container").append("<p>inside-end</p>"); // 在 #container 末尾插入子元素 $("#container").prepend("<p>inside-start</p>"); // 在 #container 开头插入子元素 $("#container").after("<p>outside-end</p>") // 在 #container 后面插入兄弟元素 $("#container").before("<p>outside-start</p>") // 在 #container 前面插入兄弟元素 现在页面上的元素是这样的: 1 2 3 4 5 6 7 <p>outside-start</p> <div id="container"> <p>inside-start</p> <p>Container</p> <p>inside-end</p> </div> <p>outside-end</p> # jQuery 使用同一个函数来取值和赋值,根据参数数量进行不同操作。 1 2 <!-- HTML 示例 --> <h1 id="title">Title</h1> 1 2 3 4 $("#title").html() // 获取 #title 的值 $("#title").html("Another title") // 修改 #title 的值 $("#title").width() // 获取 #title 的宽度 $("#title").width(1) // 修改 #title 的宽度 # jQuery 的每个操作都会返回 jQuery 对象,所以可以进行连续操作。 1 2 3 4 5 <!-- HTML 示例 --> <div id="container"> <p>Paragraph 1</p> <p>Paragraph 2</p> </div> 1 2 3 4 5 6 7 $("div") // 选择 div 元素 .find("p") // 查找 div 里的 p 元素 .eq(1) // 选择第 2 个元素 .html("end") // 把第 2 个元素内容修改为 end .end() // 退回到上一个选中的元素,也就是 .find("p") .eq(0) // 选择第 1 个元素 .html("start") // 将第 1 个元素内容修改为 start 现在页面是 start 在上面,end 在下面。 # jQuery API Documentation You Might Not Need jQuery You-Dont-Need-jQuery jQuery - Wikipedia 数据出自 Usage Statistics and Market Share of JavaScript Libraries for Websites(存档) ↩︎

2024/10/23
articleCard.readMore

优化 Hugo 博客速度:Pjax、dynamic script、preload、minification

本文介绍了优化博客速度的几个方式:Pjax(免刷新加载页面)、dynamic script(动态插入脚本)、rel=preload(预加载)、minification(极简化)。 本博客是 Hugo 生成的静态网站,感觉访问速度还不算慢。有天我看别人的博客(大概是单页应用),发现点击链接居然没刷新网页就加载了新页面,速度非常快。那时我想:要是我的 Hugo 博客也能这么流畅就好了。我感觉把博客改成单页应用要耗费不少时间,遂作罢。 后来我发现可以用 Pjax 技术让静态网站实现免刷新加载页面。Pjax 的意思是 pushState(修改 URL)+ Ajax(asynchronous JavaScript and XML,发送请求)。通俗来说,Pjax 就是请求网页、替换内容、修改 URL,这个过程比加载整个页面更快。 搜索 Pjax 库,找到两个好几年没更新的库(MoOx/pjax、defunkt/jquery-pjax),我不想用不维护的库。我快放弃的时候发现了一个支持 Pjax 的 Hugo 主题:hugo-theme-luna,从自述文件可以看出 Pjax 是用 swup 实现的,然后我就用它了。 # 如果网站没有 JavaScript 代码,那直接加载 swup 就好了。 建议使用这些插件: Head Plugin:刷新 <head> 元素的内容和 <html> 元素的 lang 属性。 Preload Plugin:光标在链接时预加载 URL,用户点击时就会内容会马上替换,还可以配置自动加载出现在可见区域的链接。 Progress Bar Plugin:加载时间较长时显示进度条。 注意要先加载插件再加载 swup。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <script src="https://unpkg.com/@swup/head-plugin@2"></script> <script src="https://unpkg.com/@swup/preload-plugin@3"></script> <script src="https://unpkg.com/@swup/progress-plugin@3"></script> <script src="https://unpkg.com/swup@4"></script> <script> const swup = new Swup({ containers: ["body"], // 替换 <body> 的内容 plugins: [ new SwupHeadPlugin(), new SwupPreloadPlugin({ preloadVisibleLinks: true }), // 预加载页面可见的链接 new SwupProgressPlugin(), ], }); </script> 我的博客用到了 3 个 JavaScript 程序:Google Analytics(流量统计)、Giscus(评论服务)、Disqus(评论服务),用了 swup 之后要考虑是否需要额外处理。 读者点击链接加载新页面后的处理: Google Analytics:参考 Measure single-page applications | Google Analytics | Google for Developers,打开 Enhanced measurement 就可以检测页面变化了。 Giscus:加载。 Disqus:重置(reset)或者加载。 # 我写了个动态插入脚本的函数,可以设置等待时间、加载前执行的函数、async、加载后执行的函数、attribute。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 function loadScript({ url, delay, onloadCallback, async, preloadCallback, attributes = {}, }) { function load() { if (preloadCallback) preloadCallback(); const script = document.createElement("script"); script.src = url; script.async = async; // Set attributes Object.entries(attributes).forEach(([key, value]) => { script.setAttribute(key, value); }); if (onloadCallback) script.onload = onloadCallback; document.body.appendChild(script); } if (typeof delay !== "undefined") { setTimeout(load, delay); } else { load(); } } 我给 Google Analytics、Giscus、Disqus 加了 100ms 等待时间,给 swup 添加了 200ms 等待时间。 # 在 <link> 标签使用 rel="preload" 可以让浏览器提前下载资源(字体、图片、脚本、样式等),后面动态插入脚本时浏览器就可以马上执行下载好的脚本。 示例: 1 2 3 4 5 <head> <link rel="preload" as="script" href="https://unpkg.com/@swup/head-plugin@2"> <link rel="preload" as="script" href="https://unpkg.com/@swup/preload-plugin@3"> <link rel="preload" as="script" href="https://unpkg.com/swup@4"> </head> preload 应该叫 predownload,因为它并不会提前加载脚本,只是提前下载。 # 这次优化博客没用到极简化,不过既然讲到优化博客了,就顺便说一下吧。极简化就是移除代码中不必要的内容(比如:空格、空行、缩进),从而减小文件大小,这样浏览器就能更快下载完网页。 Hugo 可以极简化 HTML、CSS 和 JavaScript 文件。本博客的代码用 Hugo 极简化了。举个例子,样式文件大小原本是 13.8 kB,经过极简化后是 7.4 kB(原文件的 53.6%),传输过程中再经过 Brotli 压缩后是 2.1 kB(原文件的 15.2%)。 # 以下是这次优化用到的代码: preload Pjax、dynamic script # 我已经用 swup 两三天了,非常满意,真没想到静态网站可以变成单页应用。Preload 插件能让浏览器会自动提前加载页面,读者点击链接时页面会瞬间加载,这个感觉太爽啦! # 天下武功,唯快不破 —— 我是这样优化博客的 | Sukka’s Blog rel=preload - HTML: HyperText Markup Language | MDN swup 文档

2024/10/18
articleCard.readMore

将 LineageOS 20 升级到 LineageOS 21

我手机用的系统是开源的 LineageOS 20(Android 13),跨版本升级到 LineageOS 21(Android 14)需要用电脑手动操作。因为怕操作失误导致无法开机,所以想着先备份资料,但我懒得备份资料,于是好几个月没升级。今天就来升级了。 # 虽然升级 LineageOS 不会清空储存空间,但为了保险起见,我按照自己的需求备份以下内容: 微信聊天记录 图片 电子邮箱账户截图 闹钟截图 应用列表 # 按照 Upgrade LineageOS on lisa | LineageOS Wiki 的步骤,安装 LineageOS 21、重启到 Recovery、安装 Google Apps、重启。 这里碰到一个奇怪的问题:手机通过数据线直接插到笔记本电脑的 USB 口,用 fastboot 可以检测到设备,但安装新系统时会报错。数据线插到 USB 集线器才行。 # 升级过程比我预想的简单。系统正常运作,所以清除了前面的备份。目前遇到两个问题:状态栏的快捷设置在亮色模式下仍然是暗色;Fcitx5 输入法底下的导航栏不见了,将「导航栏背景」设置为「跟随键盘背景色」即可解决。 如果你也要升级 LineageOS,不要照搬我的步骤,要遵循 LineageOS Wiki 的步骤,不同设备的升级步骤可能有差异。

2024/10/11
articleCard.readMore

开放的心态

在网上看到有人争论同类事物的好坏(比如:Vim 和 VS Code、Arch linux 和 Ubuntu),我认为没有必要去争。纠结哪个最好容易导致无尽的争吵。没有完美的工具,我们应该去思考工具的特点和适用场景。两个工具适用场景相似时可以先随便选一个,不要追求完美,适合就继续用,不适合就换另一个。 拿厨刀举例,主厨刀(chef’s knife)和切片刀哪个好?这个问题没有绝对的答案。 主厨刀 切片刀 主厨刀更轻更小,刀尖有弧度。刀尖有弧度就可以用摇刀切(rock chop),适合切蒜末。 切片刀更重,用它切菜时更流畅,使用者更省力。切片刀更宽大,可以把食材拍扁,还可以把切好的食材铲起来倒入锅中。 所以哪把刀好还是得看使用者的偏好,如果你喜欢轻巧就用主厨刀,喜欢功能多就用切片刀。 当然其实这两把刀都能切蔬菜和肉,不是很了解的情况下任选一把即可。选其他工具也一样,没实际用过就感受不到细微的差别,与其纠结,不如先随便挑一个用着。 图片出处: File:Chef’s Knife.jpg - Wikimedia Commons File:Kitchen Knife 06 Tablespoon.JPG - Wikimedia Commons

2024/10/1
articleCard.readMore

冷泡茶教程

冷泡茶是用低温水泡的茶,苦味比热泡茶淡,有清凉感。 # 茶叶(红茶、绿茶等) 水壶 冰箱 # 茶叶与冷水的重量比例为 1:50,将茶叶与冷水加到到水壶,关闭盖子。 将水壶放入冰箱冷藏室,泡 4~8 小时。可以睡前泡,这样第二天早上就能喝了。 # 夏天到了教你泡冷泡茶 - 農業知識入口網 不同茶類之最佳冷泡條件 - 農業知識入口網

2024/9/25
articleCard.readMore

QWERTY 键盘标点符号的中英文名称

AmE 表示 American English(美式英语),BrE 表示 British English(英式英语),表格的空白表示没有对应名称。 标点 英文 中文 ~ tilde 波浪号 ! exclamation point (AmE) / exclamation mark (BrE) 感叹号 @ at sign / at symbol # hash / pound sign / number sign 井号 $ dollar sign 美元符号 % percent sign 百分号 ^ caret 脱字符 & ampersand / and sign * asterisk 星号 ( ) parenthesis (AmE) / bracket (BrE) / round bracket (BrE) 圆括号 - hyphen / minus sign 连字符/减号 + plus sign 加号 ` backtick/backquote/grave 反引号/重音符 _ underscore 下划线 = equal sign (AmE) / equals sign (BrE) 等号 { } brace / curly bracket 花括号 | verticle bar / pipe 竖线/管道 [ ] square bracket 方括号 \ backslash 反斜线/反斜杠 : colon 冒号 " double quote / double quotation mark 双引号 ; semicolon 分号 ' apostrophe / single quote / single quotation mark 撇号/单引号 < less-than sign 小于号 > greater-than sign 大于号 ? question mark 问号 , comma 逗号 . period (AmE) / full stop (BrE) 句号 / slash / forward slash (正)斜线/(正)斜杠 参考资料:Wikipedia, the free encyclopedia

2024/9/20
articleCard.readMore

少囤草稿,尽快发布

笔记软件里面的草稿越来越多,但是发布的文章却越来越少了。造成这个情况的原因有:用于写博客的时间少了、对文章的要求过高。囤着草稿是不好的,写好的文章应该发出来,为了帮助自己和他人。 刚写博客那会,我对文章内容没有太高要求,就是想着写好后几天内改几次(吐槽:这要求还不高吗),力求通俗易懂。后来写作要求提升了两次。 第一次提升要求是因为我查 Linux 资料时经常看 ArchWiki。ArchWiki 的内容又新又全面,而且注册个账号就可以贡献内容,我自己也贡献了一些内容。在这个过程中我觉得知识应该像 ArchWiki 那样,集中在一个地方,每个话题都有单独的页面,还方便大家贡献。慢慢我就不想写那些别人写过的内容,除非我能写得更好。能查到的内容就没必要写了。这就是程序员说的「Don’t repeat yourself」,不要重复产生信息。 第二次提升要求是因为我写出了排在谷歌搜索首位的文章,这给网站带来了持续的访问量,会有更多人看到我的博客,我很开心。在此之前,我一直觉得推广博客很难,到处去分享感觉就像滥发消息(spamming)。从此之后,我会优先写别人没写过的话题,写重复的话题尽量保证质量好到能排到谷歌搜索的第一页。 最近我刻意改变,将文章的重心放到帮助自己,降低要求。要求就两个:自己能读懂(可以对别人来说没那么通俗)、完整(不要写一半就发,写完初稿就可以发了)。发稿速度马上就上涨了,感觉非常好。 最近发布了四篇文章: CSS Grid 布局教程 CSS Flexbox 布局教程 CSS BEM 命名规范入门教程 Introduction to CSS BEM Naming Convention Grid 教程和 Flexbox 教程都是参考 CSS-Tricks 的教程写的。之前我也看过 CSS-Tricks 那两篇教程(CSS Flexbox Layout Guide | CSS-Tricks、CSS Grid Layout Guide | CSS-Tricks),但是自己写教程的过程中对两个 CSS 布局的理解更深入了,对我来说很有用。写好之后我哪里不懂也可以看自己写的教程,自己写的教程查起来更方便。写重复的话题可以加深理解,这也不意味着做复读机,我在写的过程中会有新的感悟,写出一些新内容。 写博客就像做开源项目,要让自己感觉舒服,对自己有用,这样才容易坚持。

2024/9/19
articleCard.readMore

菜谱:酱油蒜香炒蛋

材料 # 蛋 蒜末 酱油 # 将蛋打入碗中,不要搅拌 加酱油,搅拌均匀蛋黄和蛋清 加蒜末 下锅前搅拌 煎蛋或者炒蛋 # 可用鸡蛋或者鸭蛋,混蛋也行 可用刀将蒜头切成蒜末,越碎越好 搅拌蛋后再加酱油就看不清加了多少酱油 蒜末会沉淀,所以下锅前搅拌

2024/9/18
articleCard.readMore

CSS Grid 布局教程

CSS Grid 是二维布局方法,也就是用竖线和横线将内容划分成格子,像棋盘一样。本文只介绍常见用法,要了解全部用法请看 MDN Web Docs。推荐大家看完后做文末提到的习题。 # # display: grid | inline-grid 使元素变成网格容器,其子元素叫网格项(其他后代不算),按照网格布局排列。下面代码的 .container 是网格容器,.item 是网格项,.sub-item 不是网格项。 1 2 3 .container { display: grid; } 1 2 3 4 5 6 7 <div class="container"> <div class="item"></div> <div class="item"> <p class="sub-item"></p> </div> <div class="item"></div> </div> # 划分网格的竖线(vertical line)或横线(horizontal line)。横线方向和书写方向一致(英文是从左到右),竖线方向是从上到下。同一条网格线可以有多个名称。 虚线是网格线 # 网格布局的最小单位,就像电子表格的单元格和棋盘的格子,相邻的 2 个竖线之间和相邻的 2 条横线之间的区域。1 个网格项可以使用多个网格单元。 # 2 条相邻网格线之间的区域,也就是 1 个横排(row)或者 1 个竖排(column)。 # 由 4 条网格线划分的区域,也就是长方形,比如 1 个网格单位、4 个网格单位、6 个网格单位。 示例(A 表示网格区域): 1 2 A??? ???? 1 2 AA?? AA?? 1 2 AAA? AAA? # 显性网格有固定数量的网格轨道,比如 3×3。如果此时加入额外的网格项,网格将自动添加 auto 尺寸的隐性网格轨道,原来的显性网格轨道加上自动添加的隐性网格轨道就是隐性轨道。只定义竖网格线也可以产生隐性网格。 # fr 表示网格容器的 1 份可用空间。 1 2 3 4 5 6 7 .container { display: grid; /* 3 个竖排,比例为 1:2:1 */ grid-template-columns: 1fr 2fr 1fr; /* 3 个横排,第 1 横排为 30px,剩余横排比例为 1:1 */ grid-template-rows: 30px 1fr 1fr; } # 参考资料:minmax() - CSS: Cascading Style Sheets | MDN minmax() 函数设置最小值和最大值。下面代码表示第 1 横排的尺寸最小 50px,最大 auto(根据内容自动扩大)。 1 2 3 .container { grid-template-rows: minmax(50px, auto) 1fr 1fr; } # 参考资料:repeat() - CSS: Cascading Style Sheets | MDN repeat() 函数用于表示重复的网格轨道片段。 在线示例 1 2 3 .container { grid-template-rows: repeat(3, 1fr); /* 1fr 1fr 1fr */ } 在线示例 1 2 3 .container { grid-template-rows: 2fr repeat(2, 1fr); /* 2fr 1fr 1fr */ } 除了使用固定的数字,还可用 auto-fit 和 auto-fill。 # 网格容器可以使用以下属性。 display grid-template-columns grid-template-rows grid-template-areas grid-template grid-column-gap grid-row-gap grid-gap justify-items align-items place-items justify-content align-content place-content grid-auto-columns grid-auto-rows grid-auto-flow grid # 对元素使用,使其变成网格容器。 1 2 3 .container { display: grid | inline-grid; } 值: grid:生成 block 级网格容器 inline-grid:生成 inline 级网格容器 # 参考资料: CSS Grid Layout Guide | CSS-Tricks#aa-grid-template-columnsgrid-template-rows grid-template-columns - CSS: Cascading Style Sheets | MDN grid-template-rows - CSS: Cascading Style Sheets | MDN 示例(在线版): 1 2 3 4 5 6 7 8 9 10 11 <div class="container"> <div class="item item1">1</div> <div class="item item2">2</div> <div class="item item3">3</div> <div class="item item4">4</div> <div class="item item5">5</div> <div class="item item6">6</div> <div class="item item7">7</div> <div class="item item8">8</div> <div class="item item9">9</div> </div> 1 2 3 4 5 6 7 8 9 .container { border: 1px solid red; height: 400px; display: grid; /* 3 个竖排,比例为 1:2:1 */ grid-template-columns: 1fr 2fr 1fr; /* 3 个横排,第 1 横排为 30px,剩余横排比例为 1:1 */ grid-template-rows: 30px 1fr 1fr; } 现在网格项排列成这样: 1 2 3 1 2 3 4 5 6 7 8 9 可以用 [] 定义网格线名称,用空格分隔多个名称。 1 2 3 .container { grid-template-columns: [column1-start] 1fr [column2-start] 2fr [column3-start] 1fr [column-end another-name]; } grid-column-start 和 grid-row-start 可以改变网格项的位置,在线示例。 1 2 3 4 5 6 7 8 9 10 .container { display: grid; grid-template-columns: [column1-start] 1fr [column2-start] 2fr [column3-start] 1fr [column-end]; grid-template-rows: 30px 1fr 1fr; } .item9 { grid-column-start: column2-start; grid-row-start: 2; /* 第 2 条横线 */ } 现在 .item9 占据了 .item5 的位置。 1 2 3 1 2 3 4 9 5 6 7 8 # 参考资料:grid-template-areas - CSS: Cascading Style Sheets | MDN grid-template-areas 以网格区域名称表示网格的结构。grid-template-areas 的优点是放置网格项时不需要用网格线(数网格线或者命名真的太痛苦了)。相同名称可以用多次,表示占用多个网格单元。英文句号 . 表示不使用此网格单元。grid-area 定义元素对应的网格区域名称。 grid-template-areas 会自动使用 -start 和 -end 命名网格线。header 网格区域的起始网格线(横线与竖线)都是 header-start,终止网格线(横线与竖线)都是 header-end。同一条网格线可以有多个名称。 示例(在线版): 1 2 3 4 5 6 <div class="container"> <header>header</header> <aside>sidebar</aside> <main>main</main> <footer>footer</footer> </div> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 header,aside,main,footer { border: 1px solid green; } .container { border: 1px solid red; height: 400px; display: grid; grid-template-areas: "header header header header" "main main . aside" "footer footer footer footer"; grid-template-columns: 1fr 1fr 1fr 50px; grid-template-rows: auto; } header { grid-area: header; } aside { grid-area: aside; } main { grid-area: main; } footer { grid-area: footer; } # 参考资料: CSS Grid Layout Guide | CSS-Tricks#aa-grid-template grid-template - CSS: Cascading Style Sheets | MDN grid-template 是 grid-template-rows、grid-template-columns、grid-template-areas 的缩写。grid-template 不会重置隐性网格属性。 只设置 grid-template-rows 和 grid-template-columns 的用法是用 / 隔开两者。 示例(在线版): 1 2 3 4 5 6 7 8 9 .container { display: grid; /* 横排比例 1:1:1,竖排比例 1:3:1 */ grid-template: 1fr 1fr 1fr / 1fr 3fr 1fr; /* 等价于 grid-template-rows: 1fr 1fr 1fr; grid-template-columns: 1fr 3fr 1fr; */ } 同时设置 grid-template-rows、grid-template-columns、grid-template-areas 的用法: 先写 grid-template-areas 在每横排右边写上尺寸 在最后的横排加上 / 和竖排的尺寸(/ 从下一行开始写也行) 示例(在线版): 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 .container { border: 1px solid red; height: 400px; display: grid; grid-template: "header header header" auto "main main aside " 1fr "footer footer footer" auto / auto auto 50px; /* 等价于 grid-template-areas: "header header header" "main main aside" "footer footer footer"; grid-template-columns: auto auto 50px; grid-template-rows: auto 1fr auto; */ } # 参考资料: CSS Grid Layout Guide | CSS-Tricks#aa-column-gaprow-gapgrid-column-gapgrid-row-gap gap - CSS: Cascading Style Sheets | MDN row-gap 表示横排之间的间隔,column-gap 表示竖排之间的间隔。gap 是前面两者的缩写,使用 1 个值表示横排间隔和竖排间隔一样,使用 2 个值分别表示横排间隔是竖排间隔。 示例: 1 2 3 4 5 6 .container { row-gap: 30px; column-gap: 10px; gap: 10px; /* 竖排间隔和横排间隔都是 10px */ gap: 30px 10px; /* 横排间隔 30px,竖排间隔 10px */ } 以前这 3 个属性前面要加上 grid-,比如 grid-row-gap。带 grid- 前缀的属性已被弃用,浏览器为了保持兼容,仍然支持这些属性。 # 参考资料: CSS Grid Layout Guide | CSS-Tricks#aa-justify-items justify-items - CSS: Cascading Style Sheets | MDN justify-items 设置网格项 inline 轴(横轴)对齐方式,默认值为 stretch(占满网格单元宽度)。 1 2 3 .container { justify-items: start | end | center | stretch; } # 参考资料: CSS Grid Layout Guide | CSS-Tricks#aa-align-items align-items - CSS: Cascading Style Sheets | MDN align-items 设置网格项 block 轴(竖轴)的对齐方式,默认值为 stretch(占满网格单元高度)。baseline 表示按基线对齐。内容有多行时,first baseline 表示按照首行的基线对齐,last baseline 表示按照尾行的基线对齐。 1 2 3 .container { align-items: start | end | center | stretch | baseline | first baseline | last baseline; } # 参考资料: CSS Grid Layout Guide | CSS-Tricks#aa-place-items place-items - CSS: Cascading Style Sheets | MDN place-items 是 align-items、justify-items 的缩写。使用 1 个值同时设置 2 个属性,使用 2 个值分别设置两个属性。 1 2 3 4 .container { place-items: center; /* 正中间 */ place-items: start end; /* 右上角 */ } # 参考资料: CSS Grid Layout Guide | CSS-Tricks#aa-justify-content justify-content - CSS: Cascading Style Sheets | MDN 如果网格项的总尺寸小于网格容器的尺寸,网格容器会有多于的空白,此时网格项被放置于左上角(使用从左向右的语言)。justify-content 设置 inline 轴(横轴)的对齐方式。Flex 布局也有 justify-content,用法类似,参看 CSS Flexbox 布局教程#justify-content-主轴对齐(发布前看看这个链接对不对)。 在线示例 1 2 3 .container { justify-content: start | end | center | stretch | space-around | space-between | space-evenly; } # 参考资料: CSS Grid Layout Guide | CSS-Tricks#aa-align-content align-content - CSS: Cascading Style Sheets | MDN 如果网格项的总尺寸小于网格容器的尺寸,网格容器会有多于的空白,此时网格项被放置于左上角(使用从左向右的语言)。align-content 设置 block 轴(竖轴)的对齐方式。Flex 布局也有 align-content,用法类似。 在线示例 1 2 3 .container { align-content: start | end | center | stretch | space-around | space-between | space-evenly; } # 参考资料:place-content - CSS: Cascading Style Sheets | MDN place-content 是 align-content 和 justify-content 的缩写。用 1 个值同时设置两者,用 2 个值分别设置两者。 示例(在线示例): 1 2 3 4 5 6 7 8 9 10 11 12 13 .container { place-content: start end; /* align-content: start; justify-content: end; */ place-content: center; /* align-content: center; justify-content: center; */ } # 参考资料: CSS Grid Layout Guide | CSS-Tricks#aa-grid-auto-columnsgrid-auto-rows grid-auto-columns - CSS: Cascading Style Sheets | MDN grid-auto-rows - CSS: Cascading Style Sheets | MDN 如果网格项数量多于已定义的网格项数量,那么多出了网格项就位于隐性网格轨道。grid-auto-columns 设置竖向隐性网格轨道大小,grid-auto-rows 设置横向隐性网格轨道大小,两者默认值都是 auto。 在线示例 1 2 3 .container { grid-auto-rows: 100px; } # 参考资料: CSS Grid Layout Guide | CSS-Tricks#aa-grid-auto-flow grid-auto-flow - CSS: Cascading Style Sheets | MDN 1 2 3 .container { grid-auto-flow: row | column | row dense | column dense; } grid-auto-flow 设置网格项的放置算法。 row(默认值):横向放置网格项,必要时添加新的横排。 1 2 3 1 2 3 4 5 6 7 8 9 column:竖向放置网格项,必要时添加新的竖排,在线示例。 1 2 3 1 4 7 2 5 8 3 6 9 dense 关键词表示后面的元素可以移动到前面的空位,示例(在线示例): 1 2 3 4 5 6 7 8 <div class="container"> <div class="item item1">1</div> <div class="item item2">2</div> <div class="item item3">3</div> <div class="item item4">4</div> <div class="item item5">5</div> <div class="item item6">6</div> </div> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 .item { border: 1px solid green; } .container { border: 1px solid red; height: 200px; width: 200px; display: grid; grid-template-columns: 1fr 1fr 1fr; grid-auto-flow: row dense; /* .item3 提前放置于 .item1 右边 */ } .item1, .item2 { grid-column: span 2; /* 2fr */ } # 参考资料: CSS Grid Layout Guide | CSS-Tricks#aa-grid grid - CSS: Cascading Style Sheets | MDN grid 是 grid-template-rows、grid-template-columns、grid-template-areas、grid-auto-rows、grid-auto-columns、grid-auto-flow 的缩写。 创建显性网格时用法与 grid-template 一样。 创建隐性网格时有 2 种用法(左边设置横排,右边设置竖排,中间以 / 分隔): 显性横排,隐性竖排,grid-auto-flow 为 column:<grid-template-rows> / [ auto-flow && dense? ] <grid-auto-columns>? 隐性横排,显性竖排,grid-auto-flow 为 row:[ auto-flow && dense? ] <grid-auto-rows>? / <grid-template-columns> 显性横排隐性竖排示例(在线版): 1 2 3 4 .container { /* 横排比例 1:2:1,按照竖排方向放置网格项,竖排尺寸 50px */ grid: 1fr 2fr 1fr / auto-flow 50px; } 隐性横排显性竖排示例(在线版): 1 2 3 4 .container { /* 隐性横排,按照横排方向放置网格项,竖排比例 1:2:1 */ grid: auto-flow / 1fr 2fr 1fr; } # 网格项可以使用以下属性: grid-column-start grid-column-end grid-row-start grid-row-end grid-column grid-row grid-area justify-self align-self place-self subgrid order # 参考资料: CSS Grid Layout Guide | CSS-Tricks#aa-grid-column-startgrid-column-endgrid-row-startgrid-row-end grid-column-start - CSS: Cascading Style Sheets | MDN grid-column-end - CSS: Cascading Style Sheets | MDN grid-row-start - CSS: Cascading Style Sheets | MDN grid-row-end - CSS: Cascading Style Sheets | MDN 这几个属性通过网格线的起点与终点规定 1 个网格项的位置,默认值为 auto(自动放置)。span 数字 表示占用多少个网格轨道,不加数字时为 1。 示例(在线版): 1 2 3 4 5 6 7 8 <div class="container"> <div class="item item1">1</div> <div class="item item2">2</div> <div class="item item3">3</div> <div class="item item4">4</div> <div class="item item5">5</div> <div class="item item-x">x</div> </div> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 .container { border: 1px solid red; height: 400px; display: grid; grid-template: 1fr 1fr 1fr / 1fr [col2-start] 1fr 1fr; } .item { border: 1px solid green; } .item-x { /* 从 col2-start 竖网格线到倒数第 1 条竖网格线 */ grid-column-start: col2-start; grid-column-end: -1; /* 从第 2 条横网格线开始,占用 2 个横向网格轨道 */ grid-row-start: 2; grid-row-end: span 2; } # 参考资料: CSS Grid Layout Guide | CSS-Tricks#aa-grid-columngrid-row grid-column - CSS: Cascading Style Sheets | MDN grid-row - CSS: Cascading Style Sheets | MDN grid-column 是 grid-column-start / grid-column-end 的缩写,使用 1 个值时只设置 grid-column-start。 grid-row 是 grid-row-start / grid-row-end 的缩写,使用 1 个值时值设置 grid-row-start。 示例(在线版): 1 2 3 4 5 6 7 8 9 10 .item-x { grid-column: col2-start / -1; grid-row: 2 / span 2; /* grid-column-start: col2-start; grid-column-end: -1; grid-row-start: 2; grid-row-end: span 2; */ } # grid-area 有两个用法。一是 grid-row-start / grid-column-start / grid-row-end / grid-column-end 的缩写(吐槽:这个顺序不好读,-start 后面应该跟 -end);二是搭配 grid-template-area,使用名称指定位置。 示例(在线版): 1 2 3 4 5 6 7 8 9 10 11 12 13 .item-x { grid-area: 2 / col2-start / span 2 / -1; /* grid-column: col2-start / -1; grid-row: 2 / span 2; grid-column-start: col2-start; grid-column-end: -1; grid-row-start: 2; grid-row-end: span 2; */ } # justify-self 设置 1 个网格项的 inline 轴(横轴)对齐方式,默认值是 stretch。 1 2 3 .item { justify-self: start | end | center | stretch; } 在线示例 1 2 3 .item4 { justify-self: center; } # align-self 设置 1 个网格项的 block 轴(竖轴)对齐方式,默认是 stretch。 1 2 3 .item { align-self: start | end | center | stretch; } 在线示例 1 2 3 .item4 { align-self: end; } # 参考资料: CSS Grid Layout Guide | CSS-Tricks#aa-place-self place-self - CSS: Cascading Style Sheets | MDN place-self 是 align-self justify-self 的缩写,只使用 1 个值时同时设置两者。 示例: 1 2 3 4 .item4 { place-self: center; /* 正中间 */ place-self: end start; /* 左下角 */ } # 参考资料:Subgrid - CSS: Cascading Style Sheets | MDN 虽然 subgrid 不是属性,但用于网格项,所以列举于此。 示例(在线版): 1 2 3 4 5 6 7 8 9 10 11 <div class="container"> <div class="item item1">Item1</div> <div class="item item2">Item2</div> <div class="item item3">Item3</div> <div class="item item4">Item4</div> <div class="item item5">Item5</div> <div class="item item6">Item6, 4×4 <div class="item6-1">Item6.1, 1×1</div> <div class="item6-2">Item6.2, 1×1</div> </div> </div> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 .container { border: 1px solid red; height: 400px; display: grid; grid-template: 1fr 1fr 1fr / 1fr 1fr 1fr; gap: 10px; } .item { border: 1px solid green; } .item6 { border: 1px solid yellow; grid-area: 2 / 2 / span 2 / span 2; display: grid; /* 用 subgrid 才能继承容器的 gap 属性, 可以删掉下面两行代码看看差异 */ grid-template-columns: subgrid; grid-template-rows: subgrid; } .item6-1 { border: 1px solid blue; /* 使用 .item6 的网格线编号,不要用 .container 的网格线编号 */ grid-column-start: 2; grid-row-start: 2; } .item6-2 { border: 1px solid blue; grid-column-start: 2; grid-row-start: 1; } # 参考资料:order - CSS: Cascading Style Sheets | MDN 网格项默认按照源代码顺序出现。order 设置网格项的出现顺序,默认值为 0,可使用正数和负数。 示例(在线版): 1 2 3 4 5 6 .item1 { order: 1; } .item9 { order: -1; } # auto-fill/auto-fit(Auto-Sizing Columns In CSS Grid: auto-fill Vs auto-fit | CSS-Tricks) min-content/max-content(Intrinsic size - MDN Web Docs Glossary: Definitions of Web-related terms | MDN) masonry(Masonry layout - CSS: Cascading Style Sheets | MDN) # CSS Grid Layout Guide | CSS-Tricks Grids - Learn web development | MDN An Interactive Guide to CSS Grid • Josh W. Comeau CSS Grid Layout Module Level 1 CSS Grid Layout Module Level 2 Subgrid - CSS: Cascading Style Sheets | MDN Basic concepts of grid layout - CSS: Cascading Style Sheets | MDN Auto-Sizing Columns In CSS Grid: auto-fill Vs auto-fit | CSS-Tricks # 本文使用的图片出自 CSS Grid Layout Module Level 1#grid-concepts。 # Test your skills: Grid - Learn web development | MDN Grid Garden - A game for learning CSS grid

2024/9/16
articleCard.readMore

CSS BEM 命名规范入门教程

BEM(Block, Element, Modifier)是 HTML/CSS 类的命名方法,它可以让 HTML 和 CSS 代码更有条理。 # 一开始看不懂没关系,后面有示例。 block(块):可以独立使用的 HTML 元素(比如:<nav>),可以不包含 element。 element(元素):依附于 block 的 HTML 元素,无法独立存在(比如:<li>),前面要加上双下划线 __。 modifier(修饰符):表示 block 或者 element 的状态和外观,前面要加上双连字符 --。 用单连字符 - 连接单词,比如:search-form。 element 只属于 block,而不是另一个 element。错误写法:block__element1__element2,正确写法:block__element2。 使用 modifier 时,同时保留不含 modifier 的类名,比如:<a class="menu__link menu__link--active" href="/zh-cn/">主页</a>。 # <nav> 元素是 block,它包含的 element 有 <ul>、<li>、<a>。--active 是修饰符。 1 2 3 4 5 6 7 8 9 10 11 12 13 <nav class="menu"> <ul class="menu__list"> <li class="menu__item"> <a class="menu__link menu__link--active" href="/zh-cn/">主页</a> </li> <li class="menu__item"> <a class="menu__link" href="/zh-cn/posts/">文章</a> </li> <li class="menu__item"> <a class="menu__link" href="/zh-cn/about/">关于</a> </li> </ul> </nav> # 在线示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 /* 横向列表 */ .menu__list { display: flex; flex-direction: row; flex-wrap: wrap; justify-content: space-between; list-style-type: none; padding-inline-start: 0; } /* 加粗和当前页面匹配的链接 */ .menu__link--active { font-weight: bolder; } # 我更推荐用 SCSS,用父选择器 & 可以把 block 和 element 的样式都放在一起,这种结构可以清晰地展现它们的层级关系。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 .menu { // 横向列表 &__list { display: flex; flex-direction: row; flex-wrap: wrap; justify-content: space-between; list-style-type: none; padding-inline-start: 0; } // 加粗和当前页面匹配的链接 &__link { &--active { font-weight: bolder; } } } # 如果你觉得 BEM 太冗长或者难以维护,那你可以试试原子式1 CSS 框架(atomic CSS framework),比如:Tailwind CSS 和 UnoCSS。这些框架会提供 utility(预定义的类)。开发者只需要写预定义的类名,不需要写 CSS 代码。以下是一些 Tailwind CSS 的 utility: 1 2 3 4 5 6 .flex { display: flex; } .flex-row { flex-direction: row; } 用 Tailwind CSS 重写之前的 CSS 代码(在线示例): 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 <script src="https://cdn.tailwindcss.com"></script> <script> tailwind.config = { corePlugins: { preflight: false, } } </script> <nav> <ul class="flex flex-row flex-wrap justify-between list-none ps-0"> <li> <a class="font-bold" href="/zh-cn/">主页</a> </li> <li> <a href="/zh-cn/posts/">文章</a> </li> <li> <a href="/zh-cn/about/">关于</a> </li> </ul> </nav> # https://en.bem.info/(官方教程) https://getbem.com/(非官方教程) Naming convention / Methodology / BEM troxler/awesome-css-frameworks: List of awesome CSS frameworks atomic CSS 一般译为「原子化 CSS」,我认为这个翻译是错的。「化」表示状态变化,对应英文的「-ize」和「-ify」词缀,比如:净化(purify)、标准化(standardize)。atomic 可以拆分成 atom(原子)和 -ic(形容词后缀),所以我把 atomic 翻译成原子式,「式」表示形式、样式。atomic 也可以翻译成原子型,「型」表示类型、样式。 ↩︎

2024/9/8
articleCard.readMore

CSS Flexbox 布局教程

Flexbox(弹性盒子)是一维的布局方法,也就是在一条横线(row)或者竖线(column)上排列元素。推荐大家看完本文后做文末提到的习题。 # flex 容器(flex container)的属性有 display、flex-direction、flex-wrap、flex-flow、justify-content、align-items、align-content、row-gap、column-gap、gap。 # 以下的 section 元素包含了 3 个 article 元素。 1 2 3 4 5 <section> <article>Article 1</article> <article>Article 2</article> <article>Article 3</article> </section> 要排列 article 元素,将它们的父元素设置为 flex 容器。 1 2 3 section { display: flex | inline-flex; /* inline-flex 表示容器是 inline 元素 */ } 在上述例子中,section 元素是 flex 容器(flex container),article 元素是 flex 项(flex item)。 # flex-direction 定义排列方向和主轴。 1 2 3 .container { flex-direction: row | row-reverse | column | column-reverse; } row(默认值):横向,和文字方向(dir)一致,如果方向是从左往右,那么就是从左往右排列子元素 row-reverse:和前者相反,从右往左 column:纵向,从上到下 column-reverse:和前者相反,从下到上 主轴(main axis)就是和 flex 项排列方向一致的轴,交叉轴(cross axis)则是与主轴垂直的轴。一定要分清楚方向和两条轴,在对齐 flex 项时会用到。 1 2 3 4 .container { display: flex; flex-direction: row; } 上述代码表示从左到右排列 flex 项,主轴是从左到右,交叉轴是从上到下。 轴的图示 # flex-wrap 控制是否换行,默认不换行。 1 2 3 .container { flex-wrap: nowrap | wrap | wrap-reverse; } nowrap(默认值):全部 flex 项排列成一条线 wrap:溢出时换行 wrap-reverse:溢出时换行,但后面的元素会排到前面 示例代码(在线示例): 1 2 3 4 5 6 7 8 9 10 11 <section> <article>Article 1</article> <article>Article 2</article> <article>Article 3</article> <article>Article 4</article> <article>Article 5</article> <article>Article 6</article> <article>Article 7</article> <article>Article 8</article> <article>Article 9</article> </section> 1 2 3 4 5 6 7 8 9 10 section { display: flex; flex-direction: row; flex-wrap: wrap-reverse; } article { width: 100%; outline: 1px solid green; } # flex-flow 是 flex-direction 和 flex-wrap 的缩写,默认值为 row nowrap。 下面两份代码效果一样: 1 2 3 4 section { flex-direction: row; flex-wrap: wrap; } 1 2 3 section { flex-flow: row wrap; } # justify-content 设置主轴的对齐方式。 1 2 3 .container { justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly | start | end | left | right ... + safe | unsafe; } 下面只介绍常用的值。 flex-start(默认):将所有 flex 项放到主轴的起点。如果主轴是 row(从左到右),那么所有 flex 项贴近左边。例子(. 表示空间):Item1Item2Item3......。 flex-end:将所有 flex 项放到主轴的终点。例子:......Item1Item2Item3。 center:将所有 flex 项放在主轴的中间。例子:....Item1Item2Item3....。 space-between:均匀分配 flex 项,每个 flex 项之间的距离一样,头部 flex 项贴近主轴开头,尾部 flex 项贴近主轴末尾,例子:Item1..Item2..Item3。 space-around:均匀分配 flex 项,每个 flex 项的前后间隔一样,例子:.Item1..Item2..Item3.。 space-evenly:均匀分配 flex 项,每个 flex 项之间的距离一样,头部 flex 项和主轴开头有一样的距离,尾部 flex 项和主轴末尾有一样的距离。例子:..Item1..Item2..Item3..。 # 交叉轴垂直于主轴。align-items 设置交叉轴的对齐方式。 1 2 3 .container { align-items: stretch | flex-start | flex-end | center | baseline | first baseline | last baseline | start | end | self-start | self-end + ... safe | unsafe; } align-items 用法和 justify-content 类似,这里介绍一些不一样的值。 stretch(默认值):使 flex 项填满容器。 baseline:根据基线对齐,用于字体大小不同的 flex 项,图示。 # align-content 设置多行 flex 项的交叉轴对齐方式,flex 项只有一行时(flex-wrap: nowrap;)无效,图示。 1 2 3 .container { align-content: flex-start | flex-end | center | space-between | space-around | space-evenly | stretch | start | end | baseline | first baseline | last baseline + ... safe | unsafe; } align-content 用法和 align-items 类似。 # 如果在 flex 项上画横线和竖线,row-gap 表示横线的间隔大小,column-gap 表示竖线的间隔大小,gap 是前面两者的缩写,在线示例。 1 2 3 4 5 6 7 8 .container { display: flex; flex-wrap: wrap; row-gap: 20px; column-gap: 5px; gap: 20px 5px; /* row-gap, column-gap */ gap: 20px; /* row-gap 和 column-gap 都是 20px */ } gap 只是设置最小间隔,使用 space-between 可以加大间隔。 # flex 项(flex item)的属性有 order、flex-grow、flex-shrink、flex-basis、flex、align-self。 flexbox 没有 justify-self,参看 Box alignment in flexbox - CSS: Cascading Style Sheets | MDN#there_is_no_justify-self_in_flexbox。 # 默认情况下,flex 项按照源代码出现的顺序排列。使用 order 属性可以改变顺序,默认值为 0,数字越大位置越后,可以使用负值(比如:-1)。如果多个 flex 项的 order 值一样,它们还是按原始顺序排列。 1 2 3 4 5 6 7 8 9 #item1 { order: 2; } #item2 { order: 1; } #item3 { order: -1; } 图示: 1 item3 | item2 | item1 # flex-basis 设置 flex 项的大小,默认为 auto。 1 2 3 .item { flex-basis: 50px; } # flex 容器有多余空间时,flex-grow 设置 flex 项的增长系数,默认为 0(不增长),负值无效。 1 2 3 4 5 6 7 8 9 10 11 .item1 { flex-grow: 1; } .item2 { flex-grow: 2; } .item3 { flex-grow: 1; } 上面代码表示将多余空间(假设为 100px)均分为 4 份,.item1 的宽度增加 1 份(25px),.item2 的宽度增加 2 份(50px),.item3 的宽度增加 1 份(25px),在线示例。 # 空间不足时,flex-shrink 设置 flex 项的收缩指数,默认为 1(可收缩),0 表示不可收缩,负值无效。flex-shrink 的效果和 flex-grow 类似。 假设有 1 个 200px 宽度的 flex 容器,它包含 3 个 flex 项(每个宽度 100px,共 300px),此时有 100px 溢出的宽度。 1 2 3 4 5 6 7 .container { display: flex; width: 200px; } .item { flex-basis: 100px; } 如果 flex 项总宽度减去 100px,那么就不会溢出,在线示例。 1 2 3 4 5 6 7 8 9 .item1 { flex-shrink: 1; } .item2 { flex-shrink: 2; } .item3 { flex-shrink: 1; } 上面代码表示把溢出的 100px 均分为 4 份。.item1 宽度减去 1 份(25px),变成 75px;.item2 宽度减去 2 份(50px),变成 50px;.item3 宽度减去 1 份(25px),变成 75px。 # flex 是 flex-grow、flex-shrink 和 flex-basis 的缩写,默认为 0 1 auto。推荐使用 flex 代替那 3 个属性,它会自动使用合理的默认值。比如使用 flex: 1 设置 flex-grow: 1 时,flex-basis 会变成 0%。 flex 可以使用 1~3 个值,具体用法请看 flex - CSS: Cascading Style Sheets | MDN。 使用 flex 可以轻松设置 flex 项的大小比例,在线示例。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 .container { display: flex; flex-direction: row; width: 100px; } .item1 { /* 25px */ flex: 1; } .item2 { /* 50px */ flex: 2; } .item3 { /* 25px */ flex: 1; } # align-self 设置单个 flex 项的交叉轴对齐方式,用法和 align-items 一样,两者可以同时用。 # Flexbox Froggy(点底下的 Settings 可以设置难度和语言,可以先用中等难度,不懂再调到新手难度看提示。第 24 题难得离谱,现实中不会遇到这种情况,想不到就去查答案吧。) Test your skills: Flexbox - Learn web development | MDN # CSS Flexbox Layout Guide | CSS-Tricks Flexbox - Learn web development | MDN CSS Flexible Box Layout Module Level 1(文中图片出自此)

2024/9/6
articleCard.readMore

用柠檬酸和热水去除电热水瓶和保温瓶的水垢

柠檬酸是天然的清洁剂,可去除电热水瓶和保温瓶内的顽固水垢。它的用法是先浸泡,后清洗。如果水垢未完全清除,可以重复上述步骤。 # 柠檬酸除垢剂 # 倒入冷水和柠檬酸(用量请参考说明书)。 煮沸后继续浸泡 30 分钟。 # 先倒入热水,再倒柠檬酸。 浸泡 3~4 小时。 # 电热水瓶和保温瓶的清洗方法是一样的。 倒掉混合液。 用清水冲洗。 如果冲洗后还有水垢,可以用厨房抹布擦。如果手无法伸入瓶内,可以用筷子抵住抹布擦拭。

2024/8/31
articleCard.readMore

2024-08-03 本站改动:使用 Yue 主题和 giscus 评论,post 目录改为 posts

本文列举了本站于2024年7月28日至2024年08月03日的改动。 清理无用文件 使用我写的 Yue 主题(感觉自己从几乎不折腾博客一下走到折腾博客的尽头了,用自己的主题太爽了,哈哈) 讲 utterances 评论服务改为 giscus(终于可以回复评论了,不需要引用文字或者 @) 将 post 文件夹改为 posts 改动很多,最好在 Git 仓库建一个分支搭配子域名(如 test.cyrusyip.org)测试,没问题再合并代码至主分支。修改网站要注意功能和链接(URL)变动,改了链接要修改文章内部链接、重定向、迁移评论。 # 不再使用以下软件/服务: blogdown Netlify Vercel …… 删除相关文件,修订自述文件和 package.json。 # 先构建一次,保存起来 1 2 3 4 cd cyrusyip-blog mkdir ~/Desktop/blog-builds rm -r public; npx hugo # hugo 前面多了 npx 是因为我用 npm 安装 hugo mv public ~/Desktop/blog-builds/jane 删除 Jane 主题和相关文件,重命名配置和中文内容文件夹。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 # 删除相关文件 rm -r assets layouts resources git add --all git commit --message 'chore: remove custom files related to jane theme' # 删除主题 git submodule deinit themes/jane # 修改 .git/config git rm themes/jane # 修改 .gitmodules rm -rf .git/modules/themes/jane # 删除本地文件 git commit --message 'feat!: remove jane theme' # 重命名 mv config.toml _config.toml mv content/zh-cn content/zh-CN git add --all git commit --message 'refactor: rename to content/zh-CN and _config.toml' 安装主题。 1 2 git submodule add --depth=1 https://github.com/CyrusYip/hugo-theme-yue themes/hugo-theme-yue git commit --message 'feat: add hugo-theme-yue' 写新配置,对照原来的配置(_config.toml)。删掉了 keywords、description、Google Analytics、Disqus、utterances,后面再加回来。 1 2 3 cp themes/hugo-theme-yue/exampleSite/hugo.yaml . # 写好新配置后删除旧配置 rm _config.toml 构建,对比目录名和文件名变化,如果没变化表示 URL(链接)没变化。用 tree 命令列举两次构建的文件,复制到剪切板,使用 Diffchecker 对比。 1 2 3 4 5 rm -r public; npx hugo # 旧主题 tree ~/Desktop/blog-builds/jane | wl-copy # 新主题 tree ~/Desktop/blog-builds/yue | wl-copy 新主题编译的网站少了一些没用到的页码,这里无需处理。新网站还多了一篇 2021-01-29-python-calculate-utility-bills.Rmarkdown,这是 Rmarkdown 文件,不应该出现于此,在配置文件忽略它。 1 2 # hugo.yaml ignoreFiles: ["\\.Rmd$", "\\.Rmarkdown$", "_cache$", "\\.knit\\.md$", "\\.utf8\\.md$"] 构建网站后再对比,没这个 .Rmarkdown 文件了。 对比: 原主题编译的网站有 607 个目录,480 个文件,构建时间 750ms。 新主题编译的网站有 398 个目录,354 个文件,构建时间 450ms。新网站关闭了 enableGitInfo,还没添加统计和评论功能(只是加脚本应该不太会影响构建时间)。 用肉眼对比新旧网站,看看有没有问题。看样式、文章数量、日期等。 # Google Analytics utterances Disqus 只在 cyrusyip.org 上面显示 这次加上了多语言功能 图片说明文字 页脚 社交媒体、Github、Stack overflow、Twitter CC BY-NC-SA 4.0 协议 meta description keywords(meta keywords 已过时,参看 Meta Keywords:是什么、为什么不 | Sukka’s Blog) # 另建一个站点测试会比较稳妥,但这次为了节约时间就直接改了。 giscus 由 GitHub Discussions 驱动,功能比 utterances 强,支持多语言和回复评论。 转换步骤: 删除网站的 utterances 给相关 issue 打标签「Comments」,issue 不多我就直接在网页操作了,一次可以改一页,多的话用 gh issue edit 命令 开启 Discussion,新建类别「Comments」 测试 giscus 是否能新建讨论,标题是否正确 转换 issue(Comments 标签)为 discussion( Comments 类别),参看 Managing discussions - GitHub Docs#converting-issues-based-on-labels。页面显示「Open issues with label ‘Comments’ are being converted to discussions」,但是过了一两个小时都没反应,最后手动转换了。 创建 giscus.json 配置文件,限制域名,参看 giscus/ADVANCED-USAGE.md#origins 在 GitHub 卸载 utterances 把仓库名 blog-comment 改为 blog-comments,去 giscus 官网重新获取脚本(非必须步骤,这里存了超过一则评论,所以用复数 comments) # 之前用的 Even 主题 和 Jane 主题 要求内容放在 content/post 文件夹,但是标签(/tags/)和类别(/categories/)用的是复数,我觉得这非常不协调。这次换主题终于可以改成复数 posts 了。 改了之后网站链接(URL)会变化,需要重定向旧链接、修改文章内链接、迁移评论,参考我之前写的文章(真是帮了大忙): Hugo 多语言博客折腾记 把 Hugo 网站从 Vercel 搬到 Cloudflare Pages # 构建未修改的网站并保存。 1 2 3 cd cyrusyip-blog rm -r public; npx hugo mv public ~/Desktop/blog-builds/before 重命名文件夹。 1 2 mv content/en/post content/en/posts mv content/zh-CN/post content/zh-CN/posts 预览并修改配置。 1 rm -r public; npx hugo server --navigateToChanged --bind 0.0.0.0 1 2 3 4 5 6 7 8 --- a/hugo.yaml +++ b/hugo.yaml - post: /post/:year/:month/:day/:slug/ + posts: /posts/:year/:month/:day/:slug/ - pageRef: /post + pageRef: /posts 1 2 3 4 5 6 7 8 --- a/frontmatter.json +++ b/frontmatter.json - "path": "[[workspace]]/content/en/post", + "path": "[[workspace]]/content/en/posts", - "path": "[[workspace]]/content/zh-CN/post", + "path": "[[workspace]]/content/zh-CN/posts", 1 2 git add --all git commit --message "refactor: content/*/post -> content/*/posts" 关掉 Hugo 服务器,构建修改后的网站并保存。 1 2 rm -r public; npx hugo mv public ~/Desktop/blog-builds/after 复制两个网站目录的结构到剪切板,用 Diffchecker 对比。 1 2 3 4 # 旧网站,Original text tree ~/Desktop/blog-builds/before | wl-copy # 新网站,Changed text tree ~/Desktop/blog-builds/after | wl-copy 就只是 post 目录变成了 posts。 1 2 3 4 5 - /en/post + /en/posts - /zh-cn/post + /zh-cn/posts # 要将 [本站的某文章](/zh-cn/post/2021/01/01/hi/) 这样的链接改成 [本站的某文章](/zh-cn/posts/2021/01/01/hi/)。 获取包含链接的文件,并删掉不需要改的链接。 1 2 3 mkdir todo rg '\[.*\]\(/.*\)' content --only-matching >> todo/internal-links rg 'cyrusyip\.org' content >> todo/internal-links 链接记录节选: 1 2 3 content/zh-CN/posts/2021-06-19-ac2100-openwrt.md:[红米 AC2100 刷 breed 后刷回官方固件](/zh-cn/post/2022/10/16/ac2100-stock-firmware/) content/zh-CN/posts/2021-08-30-raspberry-pi-4b-openwrt.md:[在 OpenWrt 控制树莓派 Argon Mini Fan](/zh-cn/post/2021/09/15/openwrt-argon-mini-fan/) content/zh-CN/posts/2021-08-30-raspberry-pi-4b-openwrt.md:[树莓派 4B 超频教程](/zh-cn/post/2021/09/20/raspberry-pi4-overclock/) 自己手动改链接,改一条就删去一条记录。使用 hugo server --navigateToChanged 命令预览网站可以很方便地查看变化。 我一开始让 ChatGPT 写 Node.js 脚本帮我改,多番交流后它生成了一些不存在的链接,看来这个工作还是太难为它。 # 现在本站使用 Cloudflare Pages 构建,参考 Redirects · Cloudflare Pages docs 设置重定向。我有点搞不懂我之前写的一些重定向规则,所以要写好注释,未来的我会感谢现在写注释的我。 1 2 3 4 5 6 7 # static/_redirect ###################################################################### # Rename "content/{en,zh-CN}/post" to "content/{en,zh-CN}/posts" # URL changes: /en/post/ -> /en/posts/ , /zh-cn/post/ -> /zh-cn/posts/ ###################################################################### /en/post/* /en/posts/:splat 308 /zh-cn/post/* /zh-cn/posts/:splat 308 测试链接: https://cyrusyip.org/zh-cn/post/ https://cyrusyip.org/zh-cn/post/2024/04/05/i-hate-obscure-words/ https://cyrusyip.org/en/post/ https://cyrusyip.org/en/post/2023/12/20/run-different-hugo-versions/ 测试部分旧中文网站的链接 https://cyrusyip.org/about/ # 关闭 Disqus 和 giscus 评论,以免迁移时有读者留言。 # 参考教程:How to download, edit, and upload a URL Map CSV | Disqus 打开迁移工具,点击「Start URL mapper」->「you can download a CSV here」,去邮箱拿到下载链接,下载并解压。这个 CSV 里面的链接非常乱,有无评论的、带查询参数的(/?utterances=xxx)、失效链接。建一个 Git 仓库,把 CSV 文件放进去并提交,后面方便看改动。 修改 CSV,留下以 https://cyrusyip.org/zh-cn/post 和 https://cyrusyip.org/en/post 开头的。 文件节选: 1 2 https://cyrusyip.org/zh-cn/post/2021/03/08/girls-day-womens-day-and-goddesses-day/ https://cyrusyip.org/zh-cn/post/2021/01/10/remove-odor/ 在 Vim 执行 :%s/.*/&,&,现在每行都有两个一样的链接,提交改动。 1 2 https://cyrusyip.org/zh-cn/post/2021/03/08/girls-day-womens-day-and-goddesses-day/,https://cyrusyip.org/zh-cn/post/2021/03/08/girls-day-womens-day-and-goddesses-day/ https://cyrusyip.org/zh-cn/post/2021/01/10/remove-odor/,https://cyrusyip.org/zh-cn/post/2021/01/10/remove-odor/ 执行 :%s/\v(.*)(post)/\1posts,现在把每行第二个链接的 post 改成 posts,提交改动。 1 2 https://cyrusyip.org/zh-cn/post/2021/03/08/girls-day-womens-day-and-goddesses-day/,https://cyrusyip.org/zh-cn/posts/2021/03/08/girls-day-womens-day-and-goddesses-day/ https://cyrusyip.org/zh-cn/post/2021/01/10/remove-odor/,https://cyrusyip.org/zh-cn/posts/2021/01/10/remove-odor/ 把修改后的 CSV 文件上传到 Disqus 的 URL mapper。 # 将标题的 post 改为 posts。 示例: 1 2 - zh-cn/post/2024/04/05/i-hate-obscure-words/ + zh-cn/posts/2024/04/05/i-hate-obscure-words/ GitHub CLI 不支持修改 Discussion,又得手动改了。 # 这几篇文章有 Disqus 评论,打开看看是否有评论。 https://cyrusyip.org/zh-cn/post/2022/05/30/hugo-multilingual/ https://cyrusyip.org/zh-cn/post/2023/11/05/hugo-vercel-to-cloudflare-pages/ https://cyrusyip.org/en/post/2023/01/31/install-microcode-on-proxmox/ 在 Discussions 里找几篇文章,打开看看是否有评论。 https://cyrusyip.org/zh-cn/posts/2024/04/05/i-hate-obscure-words/ https://cyrusyip.org/en/post/2023/11/30/proxmox-network-config/ # 可以看到评论,重新打开 Disqus 和 giscus。

2024/8/3
articleCard.readMore

Hugo:自定义标签标题

背景 # 一开始我用 Hugo 做中文网站时打算在文章里用中文标签,但是链接里面的中文会被转换为人类读不懂的字符。比如:/zh-cn/tags/博客/ 会变成 /zh-cn/tags/%E5%8D%9A%E5%AE%A2/。我不喜欢这样,当时搜索一番也没找到办法,就用英文标签了。现在终于知道怎么改了,最终改为链接里面还是用英文,但是页面就显示中文。 下面是针对 hugo-theme-jane(ef8a126)主题的更改方法,方法是通用的,但是不同主题修改的部分可能不同。开始前先厘清两个概念:标签名(tag name)、标签标题(tag title)。在文章前页(front matter)写的是标签名,用于链接;在 _index.md 文件定义的是 title 是标签标题,它会显示于页面。 1 2 3 4 5 6 --- # /content/zh-cn/post/2021-03-21-dongman.md title: 动漫这个词不能再用了 tags: - anime # 标签名 --- 1 2 3 4 --- # /content/zh-cn/tags/anime/_index.md title: 日本动画 # 标签标题 --- 如果你启用了 GitInfo 而且不想更改 lastmod,请参考 Hugo:给文章添加 lastmod(上次修改时间)。 /zh-cn/tags/*/) # 以 anime(日本动画)为例。先自定义一个标签的标题。 1 2 mkdir --parents content/zh-cn/tags/anime/ touch content/zh-cn/tags/anime/_index.md 添加内容: 1 2 3 4 --- # /content/zh-cn/tags/anime/_index.md title: 日本动画 --- 文章前页(front matter)的 tags 还是保持用 anime。 1 2 3 4 5 6 --- # /content/zh-cn/post/2021-03-21-dongman.md title: 动漫这个词不能再用了 tags: - anime --- 现在 /zh-cn/tags/anime/ 会显示「日本动画」。 /zh-cn/post/*) # 在浏览器 inspect 找到 CSS 类,然后去 VS Code 搜索。 本地预览网站。随便打开一篇文章(http://localhost:1313/zh-cn/post/2022/12/03/ajin-oad/),滚动到底部的标签,右击 Inspect,可以看到对于的 HTML 代码。 1 2 3 <div class="post-tags"> <a href="http://localhost:1313/zh-cn/tags/anime/">anime</a> </div> 搜索主题目录。 1 rg '<div class="post-tags">' themes/jane 可以发现此代码就在 themes/jane/layouts/post/single.html,将其复制到 layouts/post/(我之前复制过,这次跳过此步骤)。 编辑 layouts/post/single.html。 找到下面这段代码: 1 2 3 4 5 6 7 8 <div class="post-tags"> {{ range . }} {{- $name := . -}} {{- with $.Site.GetPage "taxonomy" (printf "tags/%s" $name) | default ($.Site.GetPage "taxonomy" (printf "tags/%s" ($name | urlize))) -}} <a href="{{ .Permalink }}">{{ $name }}</a> {{ end -}} {{ end }} </div> 将 <a href="{{ .Permalink }}">{{ $name }}</a> 里面的 $name 改为 .LinkTitle。改完是这样的: 1 <a href="{{ .Permalink }}">{{ .LinkTitle }}</a> 现在 http://localhost:1313/zh-cn/post/2021/03/21/dongman/ 底下会显示标签「日本动画」。 /zh-cn/tags/) # 用前面的方法 Inspect 元素并搜索代码。 1 rg '<div class="tag-cloud-tags">' themes/jane 可以发现标签列表页面的模板为 themes/jane/layouts/_default/terms.html,复制一份到根目录再改。 1 2 3 4 mkdir --parents layouts/_default/ cp themes/jane/layouts/_default/terms.html layouts/_default/ git add layouts/_default/terms.html git commit --message 'chore: copy layouts/_default/terms.html' 打开 layouts/_default/terms.html,搜索 tag-cloud-tags,找到这段代码。 1 2 3 4 5 6 <div class="tag-cloud-tags"> ... <a href="{{ .Permalink }}" style="font-size:{{$currentFontSize}}{{$fontUnit}}">{{ $tagName }}</a> ... </div> 将里面的 $tagName 改为 .LinkTitle: 1 2 <a href="{{ .Permalink }}" style="font-size:{{$currentFontSize}}{{$fontUnit}}">{{ .LinkTitle }}</a> 提交改动。 1 2 git add layouts/_default/terms.html layouts/post/single.html git commit --message 'feat: use tag title' # 标签名全部改成全小写,以连字符分割。改动比较多,新建一个分支,提交完再合并到主分支。 1 git switch --create customize-tag-titles 使用 VS Code 插件 Front Matter CMS 修改标签名。 加标签标题就比较繁琐,要自己创建文件。我让 ChatGPT 给我写了个脚本,好使! 我说的话: I am customizing tag titles in a Hugo website. I want you to create a CLI program. 1 create-tag-title directory tag-name tag-title If I run 1 create-tag-title content/en arch-linux 'Arch Linux' the program should create content/en/tags/arch-linux/_index.md, the content of _index.md should be: 1 2 3 --- title: Arch Linux --- ChatGPT 给的 Python 脚本(Shebang 是我加的1): 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 #!/usr/bin/env python import os import sys def create_tag_title(directory, tag_name, tag_title): # Construct the path to the tag directory tag_dir = os.path.join(directory, 'tags', tag_name) # Make the directories if they don't exist os.makedirs(tag_dir, exist_ok=True) # Define the path for the _index.md file index_file_path = os.path.join(tag_dir, '_index.md') # Define the content of the _index.md file index_content = f"""--- title: {tag_title} --- """ # Write the content to the _index.md file with open(index_file_path, 'w') as index_file: index_file.write(index_content) print(f"Created {index_file_path} with title: {tag_title}") if __name__ == '__main__': # Ensure the correct number of arguments are provided if len(sys.argv) != 4: print("Usage: create-tag-title directory tag-name tag-title") sys.exit(1) # Read the arguments from the command line directory = sys.argv[1] tag_name = sys.argv[2] tag_title = sys.argv[3] # Call the function to create the tag title file create_tag_title(directory, tag_name, tag_title) 自己写提交信息还是太繁琐,让 ChatGPT 把这部分也加上。 我说的话: Besides creating the _index.md, I want to stage content/ directory and commit. Example: 1 git add content/; git commit -m 'tag-title: arch-linux -> Arch Linux' ChatGPT 返回的代码(Shellbang 是我加的): 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 #!/usr/bin/env python import os import sys import subprocess def create_tag_title(directory, tag_name, tag_title): # Construct the path to the tag directory tag_dir = os.path.join(directory, 'tags', tag_name) # Make the directories if they don't exist os.makedirs(tag_dir, exist_ok=True) # Define the path for the _index.md file index_file_path = os.path.join(tag_dir, '_index.md') # Define the content of the _index.md file index_content = f"""--- title: {tag_title} --- """ # Write the content to the _index.md file with open(index_file_path, 'w') as index_file: index_file.write(index_content) print(f"Created {index_file_path} with title: {tag_title}") # Stage the content directory try: subprocess.run(['git', 'add', directory], check=True) print(f"Staged {directory}") # Commit the changes commit_message = f'tag-title: {tag_name} -> {tag_title}' subprocess.run(['git', 'commit', '-m', commit_message], check=True) print(f"Committed with message: '{commit_message}'") except subprocess.CalledProcessError as e: print(f"Error during git operation: {e}") if __name__ == '__main__': # Ensure the correct number of arguments are provided if len(sys.argv) != 4: print("Usage: create-tag-title directory tag-name tag-title") sys.exit(1) # Read the arguments from the command line directory = sys.argv[1] tag_name = sys.argv[2] tag_title = sys.argv[3] # Call the function to create the tag title file create_tag_title(directory, tag_name, tag_title) 我使用的 Python 版本是 3.12.4。 # 可以在修改前后构建网站,用于对比。如果链接有变化,需要重定向旧链接。改了一堆东西,我已经没心思检查了,忽略此步骤。 # Custom slug encoding rules for tags, titles, taxonomies - support - HUGO https://github.com/adityatelange/hugo-PaperMod/blob/3f50861a0ced88f9b614a43662edeb4c0bc45da8/layouts/_default/single.html#L49 写完文章我才想到可以让 ChatGPT 加 Shebang ↩︎

2024/7/9
articleCard.readMore

菜谱:煎荷包蛋

材料与工具 # 冷藏的鸡蛋(1 个约 51g) 电磁炉 精铁平底炒锅(已开锅) 花生油(不要使用菜籽油这种低闪点的油,热锅后倒下去可能会着火) 锅铲 筷子 计时器 两个碗(一个装鸡蛋,另一个装少量水) # 打蛋到碗里 打开计时器记录热锅时间(后面会用到),电磁炉开到最高档位(2200w)。用手沾一点点水甩入锅,如果直接蒸发就是温度不够,如果水珠弹跳说明温度够了,记下热锅时间,重置计时器,等水珠蒸发。 暂停电磁炉,倒油,摇晃锅使锅底都被油覆盖 倒蛋,马上调到 500W1,按下计时器 等大概 1.5 分钟。等待期间可用锅铲轻推蛋的底部,若不能推动则等待15秒再推,重复此过程直至蛋可以推开。这段时间可以加白胡椒粉2调味。 铲蛋,用筷子夹住边缘并慢慢地翻面 大概煎40秒,试着用锅铲轻推,如果不行就等待后再推,能推开就可以铲起来吃了。 # 如果粘锅了,洗锅、烧干水,从头开始 如果没粘锅,铲走残渣后按照第一次的流程煎蛋 注意现在锅里有油,不要洒水测试温度,水和油混合会炸开,请参考第一次记录的热锅时间进行热锅 # 蛋下锅那瞬间温度要够高,之后根据你的喜好调节温度和煎的时间 要脆的就用更大档位 要嫩的就用更小档位 要溏心蛋就减少煎的时间 要太阳蛋(单面荷包蛋)就一面煎好后加水稍微覆盖锅底,合盖利用蒸汽煮熟热蛋的上面 粘锅时等待一段时间鸡蛋会放开锅底 多加油更容易成功,熟练后再根据自己的喜好调节油量 鸡蛋也可以用常温的 可以直接打蛋到锅中,但是蛋壳弄进去就没法拿出来了,如果你会铁砂掌也可以拿 测试温度的原理是莱顿弗罗斯特现象,水接触温度远超其沸点的铁锅时,水底部会产生有隔热作用的蒸汽,令水沸腾的速度大大减慢 不粘锅煎蛋更容易成功,但是不要干烧,要先加油再加热 可以每次煎 2 个蛋,但是 3 个就太多了,很难翻面 我这个电磁炉 500W 时是间隔加热,持续加热的电磁炉应该也是可以的 ↩︎ 胡椒研磨成粉后香味会散发,不推荐用成品胡椒粉,推荐用胡椒加研磨器 ↩︎

2024/7/5
articleCard.readMore

Hugo:补全文章的 ISO 8601 日期

背景 # 本网站使用 Hugo 构建,文章日期(date)是这样的: 1 date: '2020-10-02' 这里缺少了时间和时区。于是我给全部文章都设置了同一个时区(时间没填就是 00:00:00),但这个办法有隐患。如果我在另一个时区写文章,这时新的文章还是使用了旧时区。所以最好在每篇文章写上日期、时间和时区。 Hugo 日期的格式为 ISO 8601,示例: 1 date: 2020-10-02T00:00:00+08:00 补全日期的方法就是去掉引号1、补上 T00:00:00+08:00。T00:00:00 是时间,+08:00是时区。 修改日期前先给全部文章加上 lastmod(上次修改时间),不然修改日期后 lastmod 全部变成今天了。 # 在根目录新建 use-iso8601-date.sh,添加执行权限。 1 2 touch use-iso8601-date.sh chmod +x use-iso8601-date.sh 在 use-iso8601-date.sh 填入脚本内容。 1 2 3 4 5 6 7 8 #!/usr/bin/env bash # usage: ./use-iso8601-date.sh directory-name directory="$1" files=$(find "$directory" -type f) for file in $files; do sed -i "s|date: '\(.*\)'|date: \1T00:00:00+08:00|g" "$file" sed -i 's|date: "\(.*\)"|date: \1T00:00:00+08:00|g' "$file" done 修改前先构建网站,后面用于对比。 1 2 3 rm --recursive public/ hugo mv public public-original 补全日期。 1 ./use-iso8601-date.sh content 删除时区配置。 1 2 3 4 # config.toml # 删掉下面这行 timeZone = "Etc/GMT-8" 再次构建网站。 1 2 hugo mv public public-changed 使用文件对比工具(我用的是 Kompare)对比 public-original 和 public-changed,有一处差异:/en/post/2023/11/06/hugo-top-level-404/ 文内代码块的日期也被修改了。这样改也没错。 预览,稍微和 https://cyrusyip.org/ 对比一下,看起来一样。 1 hugo server 删除构建的网站。 1 rm --recursive public public-original public-changed 查看差异后提交改动。 1 2 3 git diff git add --update git commit --message 'feat: use ISO 8601 date' 删除脚本。 1 rm use-iso8601-date.sh 日期的引号去不去都行,我觉得不用更简洁就选择去掉。 ↩︎

2024/5/25
articleCard.readMore

Hugo:给文章添加 lastmod(上次修改时间)

背景:本站文章的 lastmod(上次修改时间)就是 Git 提交的 author date(作者日期)。我需要批量修改文章(Hugo:补全文章的 ISO 8601 日期),这会导致所有文章的 lastmod 都变成今天。文章内容没变就不应该改 lastmod,所以我打算给每篇文章都加上 lastmod,后面改动文章就 lastmod 就不会变。 先把 lastmod 的优先级调至最高,不然 Hugo 会继续使用 Git 提交日期。 1 2 3 # config.toml [frontmatter] lastmod = ['lastmod', ':default'] 在根目录新建 add-lastmod.sh,添加执行权限 1 2 touch add-lastmod.sh chmod +x add-lastmod.sh 往 add-lastmod.sh 填入脚本内容。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 #!/usr/bin/env bash # usage: ./add-lastmod.sh directory-name directory="$1" files=$(find "$directory" -type f) for file in $files; do echo "${file}" lastmod_date=$(git log --no-show-signature -1 --format=%aI "$file") # example: 2024-05-16T14:23:53+08:00 echo "$lastmod_date" # Use awk to insert the lastmod line above the second --- awk -v lastmod="lastmod: $lastmod_date # remove this line if the content is actually changed" ' BEGIN { frontmatter = 0 } /^---$/ { frontmatter++ } frontmatter == 2 && !printed { print lastmod; printed = 1 } { print } ' "$file" >tmpfile && mv tmpfile "$file" done 修改前先构建网站,后面用于对比。 1 2 3 rm --recursive public/ hugo mv public public-original 添加 lastmod。 1 ./add-lastmod.sh content 再次构建网站。 1 2 hugo mv public public-changed 使用文件对比工具(我用的是 Kompare)对比 public-original 和 public-changed,结果完全相同。 预览,稍微和 https://cyrusyip.org/ 对比一下,看起来一样。 1 hugo server 删除构建的网站。 1 rm --recursive public public-original public-changed 查看差异后提交改动。 1 2 3 git diff git add --update git commit --message 'chore: add lastmod before changing date' 删除脚本。 1 rm add-lastmod.sh

2024/5/25
articleCard.readMore

拒绝烂词

最近发现自己越来越讨厌网络词语了,但是一直没细想原因,今天决定仔细思考一下。 我讨厌的词语有(次级列表表示讨厌原因): yyds -> yong yuan de shen -> 永远的神 (形容杰出的人) yyds 是拼音缩写,增加了理解难度。 IP -> intellectual property -> 知识产权(可能指「跨媒体制作」或者「网络红人」) IP 是缩写,增加了理解难度;「跨媒体制作」意思清晰,没必要发明新词;「intellectual property」意思增加了,容易造成歧义。 city walk(在城市散步) 中文已有「散步」,没必要发明 city walk。 走心(原指「变心」或者「走神」。现在网上有「用心」、「动心」的意思,贬义转褒义了) 中文已有「用心」、「动心」,没必要发明新词;「走心」的意思增加了,容易造成歧义。 百元机(1000元人民币以下的手机) 百元机(1000元以下的手机)不符合直觉,百元机按直觉应该是一百元能买到的手机。 千元机(1000元~2000元人民币的手机) 千元机(1000元~2000元人民币的手机)同样是不符合直觉。 emo(引申自 emotion,可以指一切负面情绪,比如:颓废、忧郁、悲伤) emo 意思模糊,你到底是哪种情绪呢? 这些词语的问题就是:晦涩难懂、不必要地创造新词、重新定义词语导致歧义、不符合直觉、意义模糊。语言的目的就是传递信息,而费解的词语会阻碍这个过程。我写博客时越来越追求文章通俗简洁,所以就很讨厌这些词语。看来我不是讨厌网络词语,是讨厌烂词。 世界在变化,我们需要创造新词来描述新事物。近年也有一些我觉得不错的网络词语: 全职儿女(一种职业,在家通过做家务等劳动换取父母支付的薪水。) 躺平(很形象地表达不想努力。) 打工人(突出上班就是给别人干活,有自嘲意味。) 前面批评了烂词,我也顺便从中总结我对语言的态度: 保持准确 保持通俗,使更多人理解 继续使用原有词语,能继续用就不需要发明新词 修正费解的词语。比如:鲁棒性(robustness)应该是健壮性;自行车(bicycle)不会自行移动,应该说脚踏车或者双轮车。 可以从外语引入缺乏的词语。比如:咖啡(coffee)、电话(日语借词)。 最后,推荐我自己的中文训练方法: 看到网络词语就在心中翻译 看到中英夹杂就想怎么用纯中文表达 用通俗的词语代替网络词语 表达时考虑受众的知识水平 本文图片出处: 简单点,说话的方式简单点 - 斗图表情包 - 斗图神器 - adoutu.com(使用 Bigjpg 放大 4 倍,无降噪) 你要不要聽聽看 你現在到底在講什麼(出自视频 不要再取奇怪的餐點名稱了|#吹你腦|喬瑟夫 ChillSeph - YouTube 的 0:53)

2024/4/5
articleCard.readMore

跳过 Android 应用广告

GKD 是开源的屏幕点击应用,可以自动跳过应用的开屏广告和应用内广告。实际测试 GKD 可以跳过铁路 12306 和京东的开屏广告。 使用方法: 根据官方文档安装并授予权限。 点击「订阅->右下角加号」,添加规则订阅。 默认规则订阅链接:https://fastly.jsdelivr.net/npm/@gkd-kit/subscription。默认规则于 2024 年 2 月 1日 停止更新,如果失效了可以试试第三方规则或者自己编写规则。GKD 不能跳过所有应用广告,得有对应的规则才行。

2024/3/19
articleCard.readMore

Mastodon 不是长毛象

Mastodon 是乳齿象,不是长毛象。

2024/3/12
articleCard.readMore

南华寺游记:信仰错位

这次是我第一次主动去佛寺,想去瞻仰六祖惠能真身,也感受一下佛寺的佛教氛围,要是有机会跟法师学佛法就更好啦。 南华寺的停车场免费,入场门票 20 元人民币。南华寺景色优美,也看到六祖慧能的真身1了,除了这些之外就是失望了。 去寺庙的路上听朋友说:女性月经期间不可拜佛,上山要往左走,下山要往右走。听得我双眉紧闭,佛教应该没有这等荒唐的规定吧。 正门外面有卖佛珠佛像的店,有38块、68块、98块和上百块的。老板说佛珠已开光。佛教的开光指把佛请入佛像。佛珠开光不是佛教仪式。我还听说过新车开光的,这也不是佛教仪式。这类开光似乎是道教的仪式。 刚入门居然有不属于佛教的土地公。验票后可以领三根香,我觉得烧香不环保就没拿。进去后香可置于香炉,不可拿入殿内。 大伙都在庙内烧香拜佛祈祷,求学业、前途、财富等等。我想这些人大多信的不是佛教,而是民间信仰。根据佛教的因果论,一件事能成功,其根本原因是「因」,间接原因是「缘」。以种菜为例,人认真栽培是因,天气是缘。所以佛教劝人努力,只是烧香捐钱不过是贿赂神明,自己的前途要自己打拼。同行的朋友许愿了,我没有许愿。 本来我只是来看看,不打算拜佛。但是看周围的人都在拜,感觉自己格格不入,我也从众了,我只是双手合十鞠躬,心理什么也没想。现在想想,感觉不对,没学会拜佛前还是别乱拜,不要再从众。 寺内右边有面向出家人的曹溪佛学院(本科、研究生),寺庙似乎没有面向普通人的佛教课程。南华寺名气很大,营收也不错吧。名气和资金是好东西,南华寺应该利用它们去传教帮助更多人,而不是变成民间信仰的场所。 南华寺明面上是佛寺,但是去的人又大多持有民间信仰,寺庙的管理人员也不阻止,甚至放了不属于佛教的土地公。这到底是民间信仰场所还是佛寺?我太失望了。 最后说个荒唐的小插曲。老爸听闻我要去南华寺,打电话很认真的叫我别去,他说韶关本地人在南华寺许愿不灵验,得去云门寺才灵验。老爸的话听得我想笑,我只是去参观罢了。想说我信佛了,不讲究这些,话到嘴里又咽回去。 之前稍微和爸妈提到过信佛,感觉他们不太支持,似乎他们觉得信佛就会脱离世俗十分消极。也有可能是一位亲戚给佛教抹黑了,让他们认为佛教不好。这位亲戚有段时间特别热衷于传教,打电话能讲一两个小时,不管你想不想听,这样会让人反感。我就是被这位亲戚唠叨多了就对讨厌佛教,后来才接触佛教。如果没有这位亲戚唠叨,我大概会更早接触佛教吧。 六祖惠能的真身在文化大革命中被破坏过,那真是个疯狂的时期。 ↩︎

2024/1/19
articleCard.readMore

KDE Plasma X11 黑屏后重建账号

最近 Arch Linux 升级重启后进 KDE Plasma X11 就黑屏剩下光标,某次升级后 Wayland 也用不上了。在 Arch 论坛看到一个相似的情况,但是里面的方法在我这边没用。提问和等待也要花时间,索性就新建账号吧,至少新账户用 KDE Plasma 没问题。 # 按下 Ctrl Alt F4 进入 tty 新建用户。 1 2 useradd --create-home --groups wheel --shell /bin/bash cyrus2 passwd cyrus2 按 Ctrl Alt F1(也可能是 F2 或者 F3) 返回 sddm 登录新账户。 # 软件基本都是装在系统,无需重装。 连接 WIFI 安装配置文件 安装 zinit: bash -c "$(curl --fail --show-error --silent --location https://raw.githubusercontent.com/zdharma-continuum/zinit/HEAD/scripts/install.sh)" 设置默认 Shell:chsh --shell /usr/bin/zsh 安装 kio-admin,这样 dolphin 才能用管理员权限访问旧账户的家目录 从旧账号复制配置文件 ~/.ssh ~/.gnupg ~/.local/share/keyrings/ (seahorse) 移动家目录的文件(用 dolphin 复制容易卡住,还时不时询问密码,不要一次弄太多。sudo lf 里面复制的文件权限会变 root。复制 git 仓库超慢,最好忽略。) Desktop Documents Downloads Music Pictures Videos VirtualBox VMs 登录软件 登录 Firefox 和 Brave(Brave 浏览器同步码的最后一个单词每天都不一样) 登录 Bitwarden 登录 MegaSync 同步文件,同步完后删除旧账户的网盘文件 登录 Joplin 登录 VS Code,同步设置 登录 GitHub CLI 克隆常用的 Git 仓库 配置 KDE 添加 Netspeed Widget 新建两个 Virtual Desktop 开机启动(autostart) MegaSync Fcitx5 Joplin bismuth 快捷键设置,Settings -> Shortcuts -> Shortcuts -> Window Tiling,打开需要使用的快捷键 其他快捷键 Switch to Next Screen = Meta +, 点击 Window Behavior,关闭 Active screen follows mouse,打开 Separate screen focus Lock Session = Meta+Ctrl+Space 特效 Desktop Effects -> Virtual Desktop Switching Animation -> Fade Desktop 设置 plasma-hud 快捷键 1 2 3 cp ~/.config/kwinrc{,.bak} # 备份 kwriteconfig5 --file ~/.config/kwinrc --group ModifierOnlyShortcuts --key Alt "com.github.zren.PlasmaHUD,/PlasmaHUD,com.github.zren.PlasmaHUD,toggleHUD" qdbus org.kde.KWin /KWin reconfigure GoldenDict 导入词典 清理旧家目录里不需要的文件,比如 ~/.cache # KDE Plasma 默认单击打开文件,这还挺好用的。

2023/12/5
articleCard.readMore

如何召唤人工客服

目前中国的购物网站有很多机器人客服。它们假装真人,却常常答非所问。和客服聊天先发送咒语「人工客服」就可以驱散机器人,召唤真人。如果说一次不行,就说多几次。次数越多,威力越大。

2023/11/27
articleCard.readMore

小米 / 红米 / HyperOS / MIUI 的自动通话录音教程

本文仅测试于中国版 MIUI 和 HyperOS,适用于 Redmi K40S(MIUI 14.0.7.0.TLMCNXM)、Redmi Note 12 Turbo、Redmi Turbo 3(HyperOS 1.0.16.0.UNPCNXM)。 # 通话录音: 打开设置 搜索「录音」 点击「通话录音」(应用设置/其他设置/系统应用设置/电话/通话录音) 开启「自动录音」 应用录音: 打开设置 搜索「录音」 点击「应用通话录音」(录音机) 点击「应用通话录音」 开启「应用通话录音」 同意权限 开启「自动开启录音」 选择需要录音的应用(支持微信和 QQ) # 通话录音:打开设置 -> 应用设置 -> 系统应用设置 -> 电话 -> 通话录音 -> 打开「录音通知」和「自动录音」 -> 选择「自动录音对象」 应用录音:打开设置 -> 应用设置 -> 系统应用设置 -> 录音机 -> 应用通话录音 -> 打开「应用通话录音」和「自动开启录音」-> 选择需要录音的应用(支持微信和 QQ)

2023/11/27
articleCard.readMore

把 Hugo 网站从 Vercel 搬到 Cloudflare Pages

起因 # 本 Hugo 网站原本使用 Vercel 构建,但是它只获取 Git 源代码仓库的前十次提交1,多数文章的更新时间会出错,变成最新提交的时间。于是我就改用支持克隆整个仓库的 Cloudflare Pages。本站的 RSS 订阅文件消耗流量大,搬到无限流量的 Cloudflare Pages 也比较合适。本文发布时本站已搬到 Cloudflare Pages 超过一个月,一切正常。 搬迁的主要步骤包括:写重定向配置文件、解决 Cloudflare Pages 导致的问题、创建 Cloudflare Pages 应用、删除 Vercel 项目。 # Cloudflare Pages 的重定向配置写法和 Vercel 不一样。参考 Redirects · Cloudflare Pages docs 写一份。 Vercel 的重定向配置: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 { "redirects": [ { "source": "/(index.xml)", "destination": "/zh-cn/$1" }, { "source": "/(post/index.xml)", "destination": "/zh-cn/$1" }, { "source": "/(about|subscribe|donate)(/?)", "destination": "/zh-cn/$1$2" }, { "source": "(/post/[0-9].*)", "destination": "/zh-cn$1" }, { "source": "/(tags|categories)(/?.*)", "destination": "/zh-cn/$1$2" } ] } Cloudflare Pages 的重定向配置: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 # This file is used by Cloudflare Pages # To improve performance, put splats and placeholders to the bottom ########################### ### Old Chinese Website ### ########################### ## RSS /index.xml /zh-cn/index.xml 308 /index.xml/ /zh-cn/index.xml 308 /post/index.xml /zh-cn/post/index.xml 308 /post/index.xml/ /zh-cn/post/index.xml 308 ## Menu /about /zh-cn/about/ 308 /about/ /zh-cn/about/ 308 /subscribe /zh-cn/subscribe/ 308 /subscribe/ /zh-cn/subscribe/ 308 /donate /zh-cn/donate/ 308 /donate/ /zh-cn/donate/ 308 /tags /zh-cn/tags/ 308 /categories /zh-cn/categories/ 308 /tags/* /zh-cn/tags/:splat 308 /categories/* /zh-cn/categories/:splat 308 ## Post /post/:year/:month/:day/:slug /zh-cn/post/:year/:month/:day/:slug/ 308 /post/:year/:month/:day/:slug/ /zh-cn/post/:year/:month/:day/:slug/ 308 # Examples: # /post/2020/10/02/ubuntu-compile-goldendict # /post/2020/10/02/ubuntu-compile-goldendict/ ####################### ### Current Website ### ####################### ## RSS links shouldn't contain a trailing slash /en/index.xml/ /en/index.xml 308 /zh-cn/index.xml/ /zh-cn/index.xml 308 # 本 Hugo 多语言网站的 defaultContentLanguageInSubdir = "true" 配置导致构建网站后根目录没有 404.html 文件,/en/ 和 /zh-cn/ 才有。此时 Cloudflare 认为网站是单页应用,用户访问 /non-existent-page/ 这样的路径网页就会跳转到 / 并且返回 200 状态码。这是错误的行为,所以要让 Hugo 构建后根目录有 404.html。解决方法请看 Create Top-Level 404 Page for a Multilingual Hugo Site,我目前使用了自己写的 404 页面。 # 之前在 Cloudflare 设置了缓存 RSS 文件,现在不需要这些规则了,删除之。 # Cloudflare 会缓存 custom.css,改用 SCSS 格式就不会出问题。 # 使用以下配置创建 Cloudflare Pages 应用,然后配置域名。 Build settings Framework preset None Build command git fetch --unshallow && hugo Build output directory public Environment variables HUGO_VERSION 0.99.1 具体操作请看教程: Get started guide · Cloudflare Pages docs Custom domains · Cloudflare Pages docs # 重定向不支持正则表达式 一个仓库只能导入一次 不支持配置文件 # https://cyrusyip.org/index.xml https://cyrusyip.org/zh-cn/index.xml https://cyrusyip.org/zh-cn/post/index.xml https://cyrusyip.org/zh-cn/post/index.xml https://cyrusyip.org/about https://cyrusyip.org/zh-cn/about https://cyrusyip.org/subscribe https://cyrusyip.org/zh-cn/subscribe https://cyrusyip.org/donate https://cyrusyip.org/donate https://cyrusyip.org/post/2020/10/02/ubuntu-compile-goldendict/ https://cyrusyip.org/zh-cn/post/2020/10/02/ubuntu-compile-goldendict/ https://cyrusyip.org/post/2020/11/01/use-fcitx5-in-rstudio-on-kubuntu20.10/ https://cyrusyip.org/zh-cn/post/2020/11/01/use-fcitx5-in-rstudio-on-kubuntu20.10/ https://cyrusyip.org/tags https://cyrusyip.org/zh-cn/tags https://cyrusyip.org/tags/life https://cyrusyip.org/zh-cn/tags/life https://cyrusyip.org/categories https://cyrusyip.org/zh-cn/categories Configuring a Build | Vercel Docs: When you make a deployment, Vercel builds your project. During this time, Vercel performs a “shallow clone” on your Git repository using the command git clone --depth=10 (...) and fetches ten levels of git commit history. This means that only the latest ten commits are pulled and not the entire repository history. ↩︎

2023/11/5
articleCard.readMore

无需 root 修复 LineageOS 的银行应用 / SafetyNet / Play Integrity

有些银行应用在没有 root 的 LineageOS 打开会提示「不支持在 root 设备使用」,然后退出。用 Lineage Recovery 安装由 althafvly 或者你的维护者提供的 ih8sn,这样银行应用就正常了。 详细解释请看 How to Fix Banking Apps / SafetyNet / Play Integrity on LineageOS without Root。

2023/10/12
articleCard.readMore

在 Proxmox VE 安装最新 microcode

本教程介绍用 apt 命令安装最新版微码(microcode)的方法,以改善 N5105 虚拟机死机问题。为了避免弄坏系统,请勿从 unstable 软件仓库安装微码以外的软件包。本教程测试于 Proxmox VE 7.4 / 8.0.2。 微码是修复中央处理器(CPU)的固件。它在开机时被使用,应该装在宿主机(host),不要装在虚拟机(virtual machine)。Proxmox (Debian stable)仓库的微码可能是过时的,所以要从 Debian unstable 仓库安装。 # 添加 unstable 仓库,只使用 non-free-firmware 组件。 1 echo "deb http://deb.debian.org/debian/ unstable non-free-firmware" > /etc/apt/sources.list.d/debian-unstable.list 创建 /etc/apt/preferences.d/unstable-repo 配置文件,添加以下内容,防止从 unstable 仓库安装其他软件包。 1 2 3 4 5 6 7 8 9 10 11 12 13 # 降低所有 unstable 仓库软件包的优先级 Package: * Pin: release o=Debian,a=unstable Pin-Priority: 10 # 允许从 unstable 仓库升级微码 Package: intel-microcode Pin: release o=Debian,a=unstable Pin-Priority: 500 # 此行应该是空行或者注释 Package: amd64-microcode Pin: release o=Debian,a=unstable Pin-Priority: 500 更新仓库,确保没有软件包从 unstable 仓库升级。 1 apt update && apt list --upgradable 根据处理器厂商安装微码软件包。 1 2 3 4 # Intel 处理器 apt install intel-microcode # AMD 处理器 apt install amd64-microcode 重启 Proxmox。 1 reboot 核实微码加载情况。 1 journalctl -k --grep="microcode updated early to" 看到和下面类似的输出信息就对了。 1 Sep 10 11:38:55 pve kernel: microcode: microcode updated early to revision 0x24000024, date = 2022-09-02 此处的 2022-09-02 和微码软件包版本不对应,它表示 Intel 上次更新本机处理器(N5105)的日期。 # 如果你不想添加 unstable 仓库,可以直接从 Debian 网站下载微码软件包。根据处理器厂商,从 amd64-microcode 或者 intel-microcode 获取最新的下载链接,使用 wget '链接' 命令下载,apt install ./文件名.deb 命令安装。 示例: 1 2 3 4 5 6 7 # AMD 处理器 wget 'http://ftp.us.debian.org/debian/pool/non-free-firmware/a/amd64-microcode/amd64-microcode_3.20230808.1.1_amd64.deb/DontCopyThisLinkVerbatim' apt install ./amd64-microcode_3.20230808.1.1_amd64.deb # Intel 处理器 wget 'http://ftp.us.debian.org/debian/pool/non-free-firmware/i/intel-microcode/intel-microcode_3.20230808.1_amd64.deb/DontCopyThisLinkVerbatim' apt install ./intel-microcode_3.20230808.1_amd64.deb # 移除微码软件包和 unstable 仓库: 1 2 3 4 5 6 7 8 9 10 11 # 移除微码软件包 apt purge amd64-microcode intel-microcode apt autoremove # 确保没有从 unstable 仓库安装软件 apt list --installed | grep '/unstable' # 移除 unstable 仓库与配置文件 rm /etc/apt/sources.list.d/debian-unstable.list /etc/apt/preferences.d/unstable-repo # 重启 reboot # 检查微码,此时应该看到 No entries journalctl -k --grep="microcode updated early to" # 我在零刻 EQ591 N5105 迷你主机安装了 Proxmox VE。一开始用得挺开心的,但部分虚拟机时不时死机,搞的我很烦。我发现很多 N5105 处理器的用户也有一样的问题,其中一个解决方法是安装微码,于是我就装上最新的微码。虽然微码没有完全解决问题,但确实大大减少了死机的情况。除此之外,我还安装了 Proxmox VE No-Subscription 仓库里最新的内核。 # Microcode - Debian Wiki Microcode - ArchWiki Do I need CPU (or any) microcode in a QEMU/KVM virtual machine? - Unix & Linux Stack Exchange apt - How to install some packages from “unstable” Debian on a computer running “stable” Debian? - Unix & Linux Stack Exchange AptConfiguration - Debian Wiki DontBreakDebian - Debian Wiki 零刻 EQ59 N5105 对应的海外型号是 Beelink U59 N5105. ↩︎

2023/9/20
articleCard.readMore

小米 / 红米 / HyperOS / MIUI 的 Google Play 安装教程

指南 # 在 Google Play 支持的设备列表1内的小米/红米手机已预装谷歌服务,我们只需要安装 Play 商店。 开启谷歌服务: HyperOS:设置 -> 更多设置 -> 帐号与同步 -> 谷歌基础服务 MIUI:设置 -> 帐号与同步 -> 谷歌基础服务 安装 Play 商店:在应用商店搜索「google play」,安装或者升级「Google Play 商店」。如果找不到就从 Aptoide 安装。 安装完桌面就有 Play 商店啦。 经测试,本文适用于 Redmi K40S、Redmi Note 12 Turbo、Redmi Turbo 3、Xiaomi 11 青春活力版、Xiaomi 14。 感谢吴诗涛测试小米 14(小米澎湃 OS)。 # 本指南不适用于所有手机,我也不知道哪些手机不行,只能你自己试试看了。 如果你还没买你想要的手机,你可以 在小米门店尝试本指南 上网买支持无理由退货的手机,尝试本指南 上网搜索是否有人在你想要的手机上按照本方法成功安装 Google Play 上网问本指南是否适用于你想要的手机 如果你已经买了手机但本指南没用,你可以 退货或者卖掉,再买另一台 解锁 bootloader 并安装自带 Google Play 的系统(对一般用户来说挺难,如果你想试试,请看 XDA Forums 和 xiaomi.eu) 这不是硬性要求。有些不在列表的手机也可以安装 Play 商店。 ↩︎

2023/5/5
articleCard.readMore

Epic 游戏商城的免费游戏

Epic 游戏商城从 2018 年 12 月 14 日开始每两周送一款游戏,2019 年 5 月 23 日开始每周至少送一款游戏。Epic 商城刚解锁中国区的时候我也跟风去每周领游戏,当时觉得只是暂时的活动,领几次停止了。几个月前我发现这个活动居然还在继续,于是我又开始每周领游戏了。虽然现在不玩游戏了,但还是觉得领游戏很快乐。 这几个月一边领游戏一边想为啥领了不玩还觉得快乐呢。大概是因为: 游戏质量不错。 感觉以后会玩领到的游戏。 成本极低。只需要花一点时间注册帐号,点点鼠标就能领了。不会抢完,完全没有套路。 时间规律,每周领一次,不用时时盯着 Epic 商城。用 RSS 订阅更新也方便。 虚拟商品不会占用空间,反观实体商品就算是免费拿回家不用会浪费空间。 现在圣诞节期间 Epic 每天都送一款游戏,真棒!

2022/12/26
articleCard.readMore

亚人 OAD 动画

最近看了两季亚人动画,看完回味无穷,可惜还没有第三季。不过亚人有三集 OAD(original animation DVD)动画,还能过把眼瘾。第一集讲的是中村慎也事件。第二集讲的是四个搞笑故事。第三集讲了佐藤在军队的经历。喜欢看亚人的朋友一定不要错过这三集。 这三集 OAD 的资源大多都是高糊画质的,实在是看不下去,最后在 https://nyaa.si 里找到了唯一的 1080p 版本(英文字幕)。中文字幕也找不到,就直接看这个版本了。

2022/12/3
articleCard.readMore

用 Cloudflare 缓存本站的订阅文件

本站目前使用 Vercel 部署。最近看了下 Vercel 的使用量,10 月份中文订阅文件(/zh-cn/index.xml)用了 17 GB 流量(平均每日 561 MB),占据了大部分流量,消耗流量第二多的文件只占 79 MB。本站 10 月就 959 次访问,没想到有那么多人订阅。Vercel 免费账户每月 100 GB 流量,真担心有一天流量超标了。 本站的订阅文件包含所有文章全文,大小是 1 MB。减少文章或者文章内容改为摘要都可以减少文件大小。只要流量不超标,我还是希望文件保持完整,给读者选择看网页或者使用 RSS 阅读器的自由。 之前听闻 Cloudflare 提供免费无限流量的 CDN 服务,那让本站使用 Cloudflare 提供的 CDN 不就能减少 Vercel 的流量吗?Vercel 官方就有相关教程:How do I use a Cloudflare domain with Vercel? – Vercel Docs。使用 CDN 之后 Vercel 流量并没有明显变化。11 月 10 号使用 Cache Rules 缓存中文和英文订阅文件,之后中文订阅文件流量降低到 100 MB 左右,效果挺好。11 月 14 日将缓存时间(Edge TTL)改为 2 小时,之后中文订阅文件流量从 55 MB 逐步变成 2.2 MB,效果极佳。11 月 22 日晚上 10 点 55 分 Cloudflare 后台显示 24 小时内缓存了 97.81% 流量。 2 小时的缓存时间虽然很省流量,但是可能导致发新文章后过 2 小时订阅文件才更新。11 月 22 日晚上 11 点 07 分我把缓存时间改为了保持原样(Respect origin),接下来三天订阅文件的流量都低于 6 MB。 以下是缓存规则的设置方法(你也可以按照自己需求来,不用和我一样): 点击域名 -> Caching -> Cache Rules 点击 Create cache rule Rule name 填写规则名称 点击 Edit expression 并填入 (http.request.uri.path eq "/zh-cn/index.xml") or (http.request.uri.path eq "/en/index.xml") 上一步对应的手动操作: Field 选择 URI Path Operator 选择 equals Value 填 /zh-cn/index.xml 点击 Or Field 选择 URI Path Operator 选择 equals Value 填 /en/index.xml Cache status 选择 Eligible for cache Edge TTL 表示多久缓存一次文件,可以不设置。如果要设置就点 Add -> Override origin,选择一个合适的时间。 点击最后的 Deploy 设置完后可以用 curl --head 检查文件缓存状态(cf-cache-status),状态含义请参看:Default Cache Behavior · Cloudflare Cache docs。 1 2 ❯ curl --head https://cyrusyip.org/zh-cn/index.xml | grep cf-cache-status cf-cache-status: REVALIDATED 折腾完之后我又在想:要是订阅文件以外的路径也很多流量怎么办(焦虑发作……)?我还是发现了一劳永逸的方法:改用无限流量的 Cloudflare Pages。Cloudflare Pages 没有超越 Vercel,两者的免费帐号各有优缺点。 Vercel Cloudflare Pages 使用量 6000 分钟 500 次 流量 100 GB 无限 配置文件 支持 不支持 Cloudflare Pages 除了流量无限,其他都比 Vercel 差。CDN 套壳算是集两家所长,但是 Vercel 文档并不推荐这样做,参看:Can I use a proxy on top of my Vercel Deployment? – Vercel Docs。目前就这样吧,慢慢观察这个方案有没有问题。

2022/11/22
articleCard.readMore

红米 AC2100 刷 breed 后刷回官方固件

相关文章:红米 AC2100 刷入 OpenWrt 固件 红米 AC2100 刷回官方固件的主要步骤:准备工具、刷入官方 bootloader、刷入官方固件。 # 官方 bootloader(找不到官方链接,我在这里下载的) Redmi路由器AC2100 稳定版固件(我下载的版本是 miwifi_rm2100_all_fb720_2.0.23.bin) 小米路由器修复工具 牙签 网线 Windows 电脑1 # LAN 插到电脑 拔下 AC2100 的电源,用牙签顶住 Reset 键,插电,蓝色灯闪烁时松开 访问 192.168.1.1 固件更新->Bootloader->选择文件->选刚刚下载的 bootloader-redmi-ac2100.bin->勾选自动重启->上传->更新 # 拔下电源,用牙签按住 Reset 键,插电,橙色灯闪烁时松开 解压修复工具,打开 MIWIFIRepairTool.x86.exe 本地上传->浏览->选择 miwifi_rm2100_all_fb720_2.0.23.bin->选择对应的网卡->下一步 蓝色灯闪烁表示成功,拔电源再接上,电脑打开 http://192.168.31.1/ 有页面就成功啦 # bootloader-redmi-ac2100.bin miwifi_rm2100_all_fb720_2.0.23.bin md5 f4ba3f7b01d2dd47c664528688166cd1 ca32a6cb7e60df65a391fe5f235fb720 sha256 e09c1a8ddb794ed237960b021ac34c0602374211cc5e589f6b2084b9fde3f96c f1e374fcecab26e6d968f24e4753f0c78543ff8819c7fd4a3e6aa6316c943994 1 2 3 4 5 6 7 8 ❯ md5sum bootloader-redmi-ac2100.bin f4ba3f7b01d2dd47c664528688166cd1 bootloader-redmi-ac2100.bin ❯ md5sum miwifi_rm2100_all_fb720_2.0.23.bin ca32a6cb7e60df65a391fe5f235fb720 miwifi_rm2100_all_fb720_2.0.23.bin ❯ sha256sum bootloader-redmi-ac2100.bin e09c1a8ddb794ed237960b021ac34c0602374211cc5e589f6b2084b9fde3f96c bootloader-redmi-ac2100.bin ❯ sha256sum miwifi_rm2100_all_fb720_2.0.23.bin f1e374fcecab26e6d968f24e4753f0c78543ff8819c7fd4a3e6aa6316c943994 miwifi_rm2100_all_fb720_2.0.23.bin 参考资料:小米/红米AC2100 刷breed后 刷回官方固件 - YouTube 小米路由器修复工具只有 Windows 版,我的系统是 Arch Linux。我用了 Virtualbox 启动 Win10 来刷机的,把 USB 网卡分配给虚拟机就行了。 ↩︎

2022/10/16
articleCard.readMore

修复奇怪的电脑问题

友情提示:你可以边看本文边猜问题的原因,这样可能比较有趣。 今天晚上电脑在 Chrome 用 Fcitx5 输入法的时候选字总是出错(奇怪现象 1),重启 Chrome 后又没事了。电脑锁屏后我就去睡觉了,半夜去上厕所的时候发现显示器和笔记本电脑屏幕都亮着,没有自动关闭(奇怪现象 2)。第二天打开 KDE Plasma 的设置看看有没有「接了显示器就不熄屏」的选项。打开「Energy Saving」,里面似乎没有相关选项。此时电脑有点不受控制,乱点里面的东西,还点击里面的选项卡了(奇怪现象 3)。俗话说,重启能解决 90% 的电脑问题。于是我就升级了 Arch Linux 并重启,但是没用。 用电脑那么多年没见过那么奇怪的事情,该不会被黑了吧。想想又不太可能,我用 Linux,黑了我电脑干坏事也得悄悄地用命令行吧,用远程桌面实在是吃力不讨好。好吧,打开 Chrome 搜索一下,不过我也不知道搜啥。打开 Chrome 之后,无论我点击哪个标签页,Chrome 都会选择它右边的标签页,再选择右边的,直至到最右边(奇怪现象 4)。同样是 Chromium 内核的 Brave 浏览器也有这个问题,但是 Firefox 就没事。 电脑的输入设备无非是鼠标和键盘,就逐个排查吧。先打开 screenkey 检测键盘输入,再点击 Chrome 标签页,问题依旧,但没有键盘输入,说明键盘没问题。接下来就打开鼠标检测软件,但我没安装。算了,直接关掉无线鼠标,用笔记本触控板点 Chrome 标签页,问题依旧。我突然想到自己写过一个检测鼠标的网页,打开一看发现输入设备一直触发向后滚动。终于确定问题了,上谷歌搜「linux mouse keep scroll」,找到相关问题:10.10 - Mouse wheel jumpy on scrolling - Ask Ubuntu。提问者也是点标签页就跳到最右边。 But I open many browser tabs, and if i just move my mouse of one of the tabs, the the right-most tab gets selected. 提问者自己回答说问题原因是低电量的无线键盘干扰了无线鼠标。 Unbelievable, but the problem was that my wireless keyboard and my wireless mouse’s receivers were both on adjacent usb ports. when i moved my mouse’s reciever to a further away port, I found that my mouse was not being weird any more, but my keyboard was acting funny. Turns out my keyboard’s battery was running low and it was interfering with my mouse. 我电脑用的无线输入设备就只有鼠标,应该没干扰吧。拔掉插在 USB 分线器的接收器再插入,问题就消失了。我还是觉得很奇怪,为什么一开始插着接收器关了鼠标还是出问题?鼠标都关了应该就不会向接收器发指令吧。

2022/8/31
articleCard.readMore

Windows 10 简易安装教程

安装系统有三个基本步骤:刻录系统映像、分区、安装。如果你要安装其他系统,也可以参考本文的步骤。 # 在谷歌或必应搜「windows 10 下载」,可以找到微软官方的下载地址,选择合适的版本。如果你不知道选啥,那就下载「Windows 10 (multi-edition ISO)」。 你也可以在 https://msdn.itellyou.cn/ 下载系统,但这不是官方网站。 # 将下载好的系统映像刻录到 U 盘就可以用来装系统了。你可以用 balenaEtcher 这种传统的刻录工具。我更推荐用 Ventoy,将它装到 U 盘之后,它就能启动 U 盘里的任意系统映像。这就免除了刻录的过程,升级 Ventoy 也无需格式化 U 盘。 # 开机时按特定按键1(如 F2)进入 BIOS/UEFI,将启动方式改为 UEFI,现在的系统似乎都用这个启动方式,我也不知道用 BIOS 启动行不行。然后再启用 USB 启动。 # 分区工具可以用 DiskGenius 或者 GParted。第三方 Windows PE 一般都有 DiskGenius,例如:优启通、微PE工具箱。有些无良 Win PE 有病毒和广告软件,所以要选择口碑良好,没出过问题的 Win PE,比如我刚刚提到那两个。选 Win PE 那么麻烦,大家赶紧用 Linux 发行版映像吧!一般的桌面 Linux 发行版映像都有分区工具,例如:Ubuntu。手动分区不是必要步骤,Windows 10 安装映像里有简单的分区工具。 # 开机时按特定按键(例如 F12)进入启动菜单,选择 U 盘启动。接下来按照指引点点鼠标就可以安装了。如果你不知道选那个版本,就用家庭版,一般电脑都预装这个版本。以后换版本不需要重装,用对应的激活码就行了。 # 正版方法:微软官方商场(现在似乎只卖 Windows 11 了) 盗版方法:淘宝卖的激活码,十块左右就行了 以上两种激活方法都是安全的。千万不要用激活软件,小心病毒。 不同品牌的电脑按键不一样,你得上网搜索你的电脑怎么进 BIOS/UEFI。 ↩︎

2022/7/14
articleCard.readMore

Hugo 多语言博客折腾记

最近在统计之都看大家讨论博客,又激起了我的折腾之心,打算把一个大坑给填了:把中文博客改为双语博客。我先建立了一个新的 Git 分支来折腾,成功后才合并到主分支。以下是详细的折腾过程。 # 我原来用的 even 主题 年久失修,作者超过一年没出来处理 Issue 和 Pull Request 了,这个主题的多语言配置也没有详细的说明和配置,于是我就改用 jane 主题,这个主题更新及时,要是出 bug 应该也容易解决。jane 主题有现成的多语言配置可以抄,而且手机页面也有目录。 这次改用 git submodule 添加主题,这样就不用把主题里的一堆文件加进 git 仓库了。 1 git submodule add https://github.com/xianmin/hugo-theme-jane.git themes/jane 配置就抄这几个文件: 1 2 3 ./exampleSite/config.toml ./exampleSite/full-config.toml ./dev-config.toml 双语配置是这样的: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 defaultContentLanguageInSubdir = "true" # Render English site under /en [permalinks] post = "/post/:year/:month/:day/:slug/" # language support # en / zh-cn / other... translations present in i18n/ defaultContentLanguage = "en" # Default language to use [langusges] [languages.en] title = "Cyrus Yip's Blog" languageName = "English" contentDir = 'content/en' # languageCode = "en" # weight = 2 [languages.zh-cn] title = "叶寻的博客" languageName = "简体中文" contentDir = 'content/zh-cn' # languageCode = "zh-cn" # weight = 1 [author] # essential # 必需 name = "Cyrus Yip 叶寻" [[languages.en.menu.main]] name = "Home" weight = 10 identifier = "home" url = "/" [[languages.en.menu.main]] name = "Archives" weight = 20 identifier = "archives" url = "/post/" [[languages.en.menu.main]] name = "Tags" weight = 30 identifier = "tags" url = "/tags/" [[languages.en.menu.main]] name = "Categories" weight = 40 identifier = "categories" url = "/categories/" [[languages.zh-cn.menu.main]] name = "主页" weight = 10 identifier = "home" url = "zh-cn/" [[languages.zh-cn.menu.main]] name = "归档" weight = 20 identifier = "archives" url = "zh-cn/post/" [[languages.zh-cn.menu.main]] name = "标签" weight = 30 identifier = "tags" url = "zh-cn/tags/" [[languages.zh-cn.menu.main]] name = "分类" weight = 40 identifier = "categories" url = "zh-cn/categories/" 内容目录改成这样: 1 2 3 4 5 6 7 8 9 10 ❯ tree content content ├── en │   ├── abount.md │   └── post │   └── 2022-05-24-hello-world.md └── zh-cn ├── about.md └── post    └── 2020-10-02-ubuntu-compile-goldendict.md # 网站改为双语之后,网站链接和原来的不一样了,需要把旧链接重定向到新链接。中文博客链接现在多了 zh-cn,以前是这样的:https://cyrusyip.org/post/2020/10/02/ubuntu-compile-goldendict/,现在要改成 https://cyrusyip.org/zh-cn/post/2020/10/02/ubuntu-compile-goldendict/。RSS 链接也要改。我用 Vercel 部署网站,所以修改 vercel.json,使用正则表达式来重定向链接。改动链接和迁移评论前最好关闭网站,以免造成同一篇文章出现两份评论。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 "redirects": [ { "source": "/post/(index.xml)", "destination": "/zh-cn/$1" }, { "source": "/(about|subscribe|donate)(/?)", "destination": "/zh-cn/$1$2" }, { "source": "(/post/[0-9].*)", "destination": "/zh-cn$1" } ] Vercel 重定向的官方文档 也没介绍它支持哪种正则表达式,我就参照益辉的配置自己尝试了。如果你像我一样对正则表达式读写困难,可以用 regex visualizer 帮助理解。修改后的完整 vercel.json 在这里。弄好之后可以用 Google Search Console 再看看有没有错误链接。 # 网站源文件里面的链接也要更改,例如:[本站的某文章](/post/2021/01/01/hi/) 要改为 [本站的某文章](/zh-cn/post/2021/01/01/hi/)、https://cyrusyip.org/post/xxx 改为 https://cyrusyip.org/zh-cn/post/xxx。 用 ripgrep 查找源文件里需要改的链接。 1 2 rg '\[.*\]\(/.*\)' content --only-matching >> todo/internal-links rg 'cyrusyip\.org' content >> todo/internal-links 修正链接。 1 sed --regexp-extended -i "s|(\[.*\]\()(/.*\))|\1/zh-cn\2|g" content/zh-cn/post/* 剩下的漏网之鱼就自己手动改了。 # 我的博客收录于下面这两个博客列表。 shidenggui/bloghub: 一群自由而有趣的灵魂,终将在此相遇 | 独立个人博客推荐导航 timqian/chinese-independent-blogs: 中文独立博客列表 于是过去提交了 pull request 改 RSS 链接。其实不改也没事,旧链接会重定向到新链接。 # 本站的评论是和文章链接绑定的,因为文章链接改变了,所以要将评论指向新的链接,不然就看不到已有的评论了。本站的评论系统是 Disqus 和 utterances。 # Disqus 评论使用 URL Mapper 修改。URL Mapper 使用 .csv 文件迁移评论,我先从 Disqus 那里拿到一个 .csv 文件。节选内容如下。 1 2 3 4 https://cyrusyip.org/about/ https://cyrusyip.org/donate/ https://cyrusyip.org/subscribe/ https://cyrusyip.org/post/2020/11/15/mute-volume-plasma/ 将它加上逗号和新链接。 1 2 3 4 https://cyrusyip.org/about/,https://cyrusyip.org/zh-cn/about/ https://cyrusyip.org/donate/,https://cyrusyip.org/zh-cn/donate/ https://cyrusyip.org/subscribe/,https://cyrusyip.org/zh-cn/subscribe/ https://cyrusyip.org/post/2020/11/15/mute-volume-plasma/,https://cyrusyip.org/zh-cn/post/2020/11/15/mute-volume-plasma/ 然后再上传到 Disqus 就可以迁移评论了,Disqus 会合并逗号两边的文章评论,并将评论移动到右边的链接。官方文档说可能需要 24 小时才完成迁移,实际上我迁移了 82 份评论,一瞬间就好了。修改 .csv 的每一行都是一样的操作:复制整行内容、加逗号、粘贴、加上 zh-cn,所以用 Vim 的 q 命令录制一次操作,然后就可以批量更改了。以下是操作视频,速度比较慢,可以调到 2 倍速观看。 视频 32 秒执行录制命令时特别慢,主要原因是 coc.nvim 和 fcitx.vim。用 Vim 默认配置(vim --clean)瞬间就完成了,看来录制命令最好在无插件下使用。我专门定义了命令来用 Vim 默认配置打开文件。 1 2 " Cv: clean vim, used for fast macro replaying command Cv silent! w | wviminfo | !vim -c 'set rnu nuw=1' -c 'file' --clean -i ~/.viminfo % Disqus 还有其他迁移方式,不过我觉得还是 URL Mapper 最稳妥。 # utterances 使用 GitHub Issue 保存评论。标题为「post/2021/10/11/build-aur-wps/」的 Issue 对应的文章链接为「https://cyrusyip.org/post/2021/10/11/build-aur-wps/」。使用 GitHub CLI 修改 Issue 标题就可以迁移评论。 保存 Issue 标题与号码,并用 Vim 打开。 1 2 3 mkdir todo gh issue --repo CyrusYip/blog-comment list > todo/utterances vim todo/utterances Issue 信息是这样的: 1 2 3 3 OPEN about/ 2021-10-05 07:07:15 +0000 UTC 2 OPEN post/2021/03/15/liangfen-shaoxiancao-guilinggao/ 2021-04-30 06:53:25 +0000 UTC 1 OPEN post/2021/03/08/girls-day-womens-day-and-goddesses-day/ 2021-03-17 14:46:31 +0000 UTC 这里用 Vim 的 q 命令批量处理上面的内容,使其变成: 1 2 3 gh issue --repo CyrusYip/blog-comment edit 3 --title 'zh-cn/about/' gh issue --repo CyrusYip/blog-comment edit 2 --title 'zh-cn/post/2021/03/15/liangfen-shaoxiancao-guilinggao/' gh issue --repo CyrusYip/blog-comment edit 1 --title 'zh-cn/post/2021/03/08/girls-day-womens-day-and-goddesses-day/' 然后在 Vim 执行 :%!bash,用 BASH 执行上面的命令。utterances 只能移动评论,不能合并评论。移动前最好关闭网站,以免造成同一篇文章出现两份评论。 # 之前我写文章都是先用 Markdown 的一级标题,但根据 MDN 和 Bing Webmaster Tools,使用多个 <h1> 标题是错误的。 Use only one <h1> per page or view. It should concisely describe the overall purpose of the content. Using more than one <h1> is allowed by the HTML specification, but is not considered a best practice. Using only one <h1> is beneficial for screenreader users. —https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Heading_Elements#usage_notes These pages have more than one <h1> tag. Multiple <h1> header tags might confuse search engine bots and website’s users. It is recommended to use only one <h1> tag per page. —SEO Reports from Bing Webmaster Tools 这次难得折腾,就彻底整改吧。依然是用正则表达式解决: 1 find content/ -type f -exec perl -0777 -i -pe 's/(?<=\n\n)(#.*)(?=\n\n)/#$1/g' {} + 上面的正则表达式查找的是「以 # 开头的行,并且它上下都有 1 个空行」,然后在查找到的内容前面增加 #,也就是增加了 1 个标题级别。处理完之后用 VS Code 手动检查,没问题就提交 commit。可以用 VS Code 搜索 ^# ,看看有没有遗漏的。 preservim/vim-markdown 的 :HeaderIncrease 和 pandoc 的 --shift-heading-level-by=1 选项也可以用来增加标题级别。但是这两个工具都有问题,vim-markdown 会将 Markdown 文件 YAML 内容后两行当成标题,pandoc 会修改 YAML 内容。还是自己老老实实写的正则表达式好。 # 用 https://realfavicongenerator.net/ 将我的头像做成 favicon,放到 /static 文件夹。 # 从 Even 主题切换到 Jane,还是遇到了一些小问题。 没有文章总数功能,Even 主题是有的(解决办法:在博客目录用 tree content/ 命令查看文件数)。 不蒜子流量统计在英文博客下仍显示中文。 不能给不同语言设置不同作者名,例如:中文博客作者是「叶寻」,英文博客作者是「Cyrus Yip」(临时解决办法:中英名字都写入作者名,也就是「Cyrus Yip 叶寻」)。 用 Vercel 部署博客时 params.gitInfo 功能会出错,本地部署就没事,不知道咋回事。 修改网站是永无止境的,这些小问题就忍忍吧,太纠结反而没时间写文章了。博客内容最重要,功能够用外观不丑就行。 # 这是我想做的一些事。先挖坑,看看有没有人帮我埋。 自动备份 utterances 评论 自动备份 Disqus 评论 # E Personal Experience | blogdown: Creating Websites with R Markdown(谢益辉的博客写作经验) iggredible/Learn-Vim: Learn Vim (the Smart Way)(Vim 教程,学完第九章 Macros 就能在迁移评论时批量处理) ziishaned: Learn regex the easy way(正则表达式入门教程) regex visualizer(正则表达式可视化工具,用于理解正则表达式,上谷歌能搜到很多) vimtutor(Vim 的官方教程,先学这个,再学 Learn-Vim)

2022/5/30
articleCard.readMore

人不应适应衣服

前些天陪女友买衣服。女友试穿了一条阔腿牛仔裤,结果裤子长到拖地了。女友说裤子太长了,能不能改短些。结果店员说拖地才好看,改短了不好看,而且这种裤子很难改。最后还是没买,女友可不想要拖地之后脏脏的裤子。 我觉得店员说话实在是不尊重人,衣服是给人用来穿,满足需求和喜好的衣服才是合适的。什么时候到人适应衣服了,真是离谱!不想改裤子就直说啊,为什么硬说拖地的裤子好看呢?! 后来我又和女友吐槽起这件事,女友说其实那条阔腿牛仔裤也好看,就是自己太矮了,穿了才拖地。我说明明是裤子太长了。

2022/5/29
articleCard.readMore

旧电脑升级未遂记

相关文章:Windows 10 简易安装教程 最近亲戚抱怨家里的台式电脑很慢,我就打算帮忙升级硬件,让电脑重获新生(苟延残喘)。电脑配置如下。 型号 Dell Optiplex 3020 备注 处理器 Intel Celeron G1840 2.8 GHz 双核双线程 内存 2*2 GB DDR3L 1600MHz 有两个内存插槽 硬盘 Seagate ST500DM002-1BD142 500 GB 用 HD Tune Pro 5.75 测得读取速度为 120MB/s 主板 40DDP 系统 Windows 7 旧电脑升级主要就是把机械硬盘换成固态硬盘,固态硬盘真的比机械硬盘快多了,用一次之后真的是再也无法忍受机械硬盘的速度了。内存 4GB,也就够用的水准,这也一并升级了吧。其他硬盘就不用管了。硬盘接口似乎只有 SATA,就买 2.5 寸 SATA 固态硬盘。内存打算买条 8GB 替换一条 2GB 的。 拆机小技巧:断电后按住电源键,主板的灯熄灭就断电了、带硅胶手套防静电。以下是升级步骤。 # 内存要买主板兼容的才行,最简单的方法就是买同类的。比如这台机原本的内存是 DDR3L1 1600MHz,那就买这样的。但我没注意,买了 DDR3 1600MHz 的内存,还好这个主版兼容这两种电压的内存。最后用一条联想 8GB DDR3 1600MHz 内存(229 元)替换一根 2GB 内存,现在内存总共 10GB。 # 这台戴尔台式机加硬盘不是扭螺丝就行的,得用它专用的支架,螺丝在支架里。这台机里面没有多余的硬盘支架,得上淘宝买这台机用的 2.5 寸硬盘支架。支架的螺丝也很坑,装硬盘的时候很容易磨损表面。第一次买的联想固态就被刮花了一点。 固态硬盘买的是联想 SL700 SATA3 240GB(185 元)。一开始把硬盘插到 SATA2 接口了,读取速度才 240MB/s,接到 SATA3 接口后速度是 440MB/s。测速结果看着还行,但用电脑的时候会突然掉速,比机械硬盘还慢。这实在是太垃圾了,退货!后来买了铠侠 TC10 480GB。 拿到铠侠 TC10 之后就装 Windows 10 了,结果装完之后年迈的 TCL 显示器就一直白屏。重启主机和显示器都没辙。别说测试硬盘了,正常使用都不行。亲戚没有修或者买显示器的意愿,本次的硬件升级计划就此结束,退了铠侠硬盘。 # 电脑满除了硬盘问题以外,软件也影响很大。亲戚家的电脑开机之后右下角就一堆软件图标,还有锁屏软件、弹窗广告、两家公司的杀毒软件(它们不会相互陷害吗?)、好多流氓软件。我爸妈用上智能手机之后我就不用每次回家都清理电脑了,我真的很多年都没看过这副景象了,真的不知道亲戚是怎么忍得了这样的电脑,我都想重装系统了。最后用杀毒软件杀毒,手动删除了一堆流氓软件,电脑竟然快了不少,达到了能用的速度。 2022 年了,Windows 还是流氓软件很多,装个软件都得小心翼翼的。Windows 是个需要学习如何使用的系统,真的不太适合不愿意花时间用电脑的人。我觉得这类人挺适合用 deepin,前提是有人帮忙安装和维护。deepin 可以安装打包好的 Windows 和安卓软件,常见的软件应该都有,简单的娱乐办公应该不成问题。 DDR3L 的 L 表示 Low Voltage(低电压)。 ↩︎

2022/5/2
articleCard.readMore

小米 9 SE 刷欧版 MIUI 记录

2023-05-19 更新:改用 LineageOS # 虽然欧版 MIUI 比大陆版流畅,但仍然经不住国产软件毒打,而且系统也没更新过,没有新功能和安全更新。于是改用开源的 LineageOS 20,没想到这台机器还能用上最新的安卓 13,和之前比升级了两个版本号呢,而且更流畅了。用了两个月还是感觉不够流畅了,这配置真的跟不上软件发展了(软件厂商你们怎么不多做优化,非要逼人换手机吗!)。在 https://lineageosdevices.com/ 和 LineageOS 设备列表 物色手机,选中小米 11 青春活力版,在京东只用 1199 块就买到了(首发价格 1999),继续用 LineageOS,体验良好。顺便一提,所有 LineageOS ROM 都需要满足严格的设备支持要求,所以它软件硬件功能正常,完全可以代替原厂系统。 # 之前看了 Pockies 写的《老妈钦点,我买了一部Redmi K30 5G版》,感觉欧版 MIUI 真是太棒了,既没有广告和无用的内置软件,还有 Google Play。我手头这台小米 9 SE 也用了两三年了,越来越卡了,用了冰箱(Ice Box)冻结应用之后还是卡。骁龙 712 + 6G 内存,好歹也是中高端配置吧,怎么就卡了呢!我需要安装一些外国软件,但这台机器没预装 Google Play,自己装上的用几次就不行了。该死,只有骁龙 800 系列的小米手机才配有 Google Play 吗? 我很早就知道国外版本的 MIUI 有 Google Play,但是要解锁 bootloader 才能装。解锁 bootloader 之后呢就可以随便刷 recovery,我担心手机丢了后别人可以通过 recovery 随便查看我的文件,所以一直没换系统。经过 Pockies 的一番指点,我才知道我的认知已经过时了,但还是不太懂。于是我在联想 ZUK Z2 Pro 刷机测试,发现只要开启了系统的加密功能,别人进 recovery 就要输入解锁密码才能读取文件(\data 分区)。MIUI 默认开启加密,所以不用担心这个问题。 # 手机里唯一值得备份的文件就是图片了,我的图片在这三个文件夹: /DCIM /Pictures /Tencent/MicroMsg/WeiXin/ 用 adb 备份软件列表,装完系统再把软件装回来。用 List My Apps 也可备份列表。 1 2 3 adb shell pm list packages -3 | cut -f 2 -d ":" > third-party-apps adb shell pm list packages -s | cut -f 2 -d ":" > system-apps adb shell pm list packages | cut -f 2 -d ":" > all-apps 用电脑微信备份聊天记录。 联系人保存在小米帐户和微软邮箱,不需要备份。 闹钟得截图记下来 这个过程还挺繁琐的,下次换手机就试试小米换机 # 官方解锁软件 SDK Platform Tools(adb 和 fastboot)(Arch Linux 装 android-tools 就行) TWRP(第三方 recovery,用于安装系统) 欧版 MIUI # 使用官方软件解锁即可。进入 fastboot 之后要安装驱动,不然识别不了。我直接解锁成功了,不需要等待。解锁过程超折腾,用了三台电脑两条数据线尝试了超多次才检测到手机。 # 先进入 fastboot。 1 adb reboot bootloader 在 Arch Linux 刷入失败。 1 2 3 ❯ fastboot flash recovery twrp-3.6.1_9-0-grus.img Sending 'recovery' (65536 KB) FAILED (Write to device failed (No such device)) fastboot: error: Command failed 在 Windows 用解锁工具里的 fastboot 就行,玄学啊。 1 2 3 4 5 .\fastboot.exe flash recovery .\twrp-3.6.1_9-0-grus.img Sending 'recovery' (65536 KB) OKAY [ 1.413s] Writing 'recovery' OKAY [ 0.316s] Finished. Total time: 1.746s .\fastboot boot twrp.img 重启时要按住「关机键和音量加键」,不然进 MIUI 后 recovery 会变成原版。 # Wipe -> Format Data 连接电脑 将刷机包拷进手机 Install -> 选中刷机包 -> Swipe to confirm Flash Reboot -> System -> do not install twrp 我安装固件的时候出现 the package is for grus 错误,在 TWRP 执行以下命令就可以解决。 1 2 setprop ro.product.device grus setprop ro.build.product grus 我刷完固件一开始进了系统,后来重启就总是自动进 TWRP,不知道为啥。重新 Format Data 之后又正常了。 # 登陆谷歌帐号 登陆小米帐户 登陆邮箱帐户 允许 outlook 自启,取消省电限制,不然会收不到通知 还原之前的图片 恢复微信聊天记录 重新设置闹钟(前面忘记记下来了) 安装软件 配置 Termux1(主要用来管理 OpenWrt) 安装常用软件:fish vim openssh 生成 ssh 密钥 将公钥加到 OpenWrt # 平时用的国产软件实在太流氓,需要用以下软件治理。下列软件只需要 adb 就能用,不需要 root,但 adb 激活重启会失效。 shizuku(提升软件权限,激活后面的小黑屋和 App Ops) brevent 黑阈(后台管理) 小黑屋(冻结软件,把软件按进棺材) App Ops(给假权限,专治不给权限就罢工的软件) 以下命令用于激活黑阈和 shizuku。 1 adb -d shell sh /data/data/me.piebridge.brevent/brevent.sh; adb shell sh /sdcard/Android/data/moe.shizuku.privileged.api/start.sh 除了用电脑激活,也可以在手机通过无线调试激活(开发者怎么想到的,好厉害!出门在外不需要用电脑激活了)。 # 用了一周,系统比原来的流畅多了,Google Play 也正常能使用。欧版 MIUI 是基于中国版 MIUI 修改的,所以功能都差不多,但有些小毛病。 自带的天气软件定位到国外了,只好手动添加地点 自带的日历没有中国假日 锁屏界面不能左滑开启相机(开启 「Shortcut from lock screen」) 不能双击电源键开闪光灯(设置 「Turn on torch」) Google Play 买应用麻烦(不能用支付宝/微信,我没有国际信用卡,不知道淘宝的礼品卡好不好使) # 本节内容出自欧版 MIUI 官网,这些特性看起来还是很棒的。 Based on China Stable / Weekly builds (except POCOF1, HMNote6Pro, HMNote8T, HMNote9ProMax, HMNote9Pro_HMNote9S, HMNote9ProEU) Enabled search gesture (swipe up) on the desktop 3way reboot menu (in dev settings) MIUI Contacts and Dialer Dark Mode (Night Mode) for all devices (In the dev settings except 9.x/10.x) Removed ads in MIUI system apps Face Unlock for all devices Vertical clock widget on lockscreen Steps counter in Assistant screen More shortcuts on left lockscreen Wake up gestures AI preloading option in MIUI Lab Fullscreen gestures Option to auto-expand first notification Notifications priority settings More edit options in Gallery app Enabled MiDrive in File Explorer Added landscape mode for SMS app Sunrise/Sunset in the weather app Google apps support integrated Removed 5GHz region restrictions Confirm dials from call logs Morning report on alarm at morning More apps supported for AOD notifications More styles for AOD screen Raise to wake gesture AOD notification received animation Default volume control stream toggle Tap fingerprint sensor to wake toggle More Camera features Double tap to lock screen Battery AI scenes Allowed disabling specific system apps Importing theme .mtz from zhuti.xiaomi.com via ThemeManager No useless Chinese bloatware apps More free RAM due to less background processes Unified flat style app icons for both system and 3rd party apps Advanced menu with color icons No any Chinese character under the full system Mi Video, Mi Music, Mi Browser: No any useless Chinese content No possibility to re-lock bootloader accidentally with flash any xiaomi.eu release Added real 27 languages translation made by Official MIUI Fansites and MIUI Fans Added EU T9 dialer support Added charging sound switch Added Screen-OFF animation Optimized GPS settings for EU Optimized Battery consumption Optimized RAM consumption Added 3D Touch to MI5S 3GB RAM version Added GSMalphabet into SMS app options Added more icons grid layout 4x5, 4x6, 4x7, 5x5, 5x6, 5x7 (depends on device) SafetyNet passed (Google Pay) Play Store Certified Deodexed Added automated tasks in Security app Added game speed booster Added erase module (magic elimination) to Gallery photo edit options Fixed low volume sound via headphone Charging screen And more, and more made by our 9 years MIUI mods experience. # 国行小米9 SE刷欧版MIUI 12.5踩坑记录 - 小z博客 Goople Play 的版本似乎停更了,安装不了软件。得去 F-droid 下载。 ↩︎

2022/4/22
articleCard.readMore

为何红茶叫 black tea

小学刚学英语的时候有个困惑我很久的问题:为什么绿茶是 green tea,红茶却不是 red tea。后来上大学的英汉对比课听到了答案:中文的颜色指茶水的颜色,英语指茶叶的颜色。红茶茶叶是黑色的,所以英语是 black tea。 中文的「茶」和英文的「tea」都有两个意思:茶叶、用茶叶沏成的饮料(茶水)。茶叶和茶水的颜色不一定相同,中文以茶水颜色区分不同的茶叶与茶水,英文则以茶叶颜色区分。 图片出处: 红茶茶水 红茶茶叶

2022/3/30
articleCard.readMore

在 Linux 上使用京东京造(Keychron)K1 SE 的功能键(F1~F12)

K1 SE 的功能键在 Linux 上就永远是媒体键,按 F12 和 fn + F12 都是增加音量。解决办法: 1 echo 2 | sudo tee /sys/module/hid_apple/parameters/fnmode 现在按功能键就是功能键,按 fn + 功能键 就是媒体键,不过重启就失效了。下面是永久生效的方法: 1 2 echo options hid_apple fnmode=2 | sudo tee -a /etc/modprobe.d/hid_apple.conf sudo mkinitcpio --allpresets 附言:京东京造 K 系列键盘就是贴了京东牌的 Keychron 键盘。 参考资料: On an Apple Keyboard under Linux, how do I make the Function keys work without the fn modifier key? - Unix & Linux Stack Exchange Apple Keyboard - ArchWiki

2022/1/18
articleCard.readMore

修复键盘映射在 VS Code 失效的问题

我将 Caps 键改为 Esc 键之后,在 VS Code 设置就失效了。修复方法:按下 Ctrl + , 打开设置,找到 Keyboard: Dispatch,将其改为 keyCode。 参考资料:Howto: Fix Caps Lock Escape Swap Not Working in VS Code

2021/12/27
articleCard.readMore

在 KDE Plasma 将 Caps 键换成 Esc 键

最近用 Vim 键位之后经常按 Esc 键,于是就打算将 Caps 键替换为 Esc 键,这样挪一下左小指就能按到。设置方法:打开设置,点击「Input Devices -> Keyboard -> Advanced -> Configure keyboard options -> Caps Lock behavior -> Swap Esc and Caps Lock -> Apply」。

2021/12/27
articleCard.readMore

VSCodeVim 自动切换 Fcitx5

在 $HOME/.config/Code/User/settings.json 加入以下内容: 1 2 3 4 5 6 { "vim.autoSwitchInputMethod.obtainIMCmd": "/usr/bin/fcitx5-remote", "vim.autoSwitchInputMethod.switchIMCmd": "/usr/bin/fcitx5-remote -t {im}", "vim.autoSwitchInputMethod.enable": true, "vim.autoSwitchInputMethod.defaultIM": "1", } 或者按下 Ctrl + , 用图形界面设置对应选项。这样退出插入模式时会将 Fcitx5 切换为英文。 参考文章:在 VSCode 的 Vim keybinding 下自動切換 fcitx 模式 | by DanSnow | Medium

2021/12/24
articleCard.readMore

修复变慢的 Arch Linux(起因:auto-cpufreq)

最近 Arch Linux 用起来有点慢,有时候桌面会卡住一两秒。我用 auto-cpufreq(1.7.2) 调节 CPU 频率,该不会是它出问题了吧。先看看数据: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 ❯ sudo auto-cpufreq --stats Note: You can quit stats mode by pressing "ctrl+c" Executed on: December 06 (Monday) - 01:05:35 ------------------------------------------------------------------------------- Linux distro: Arch Linux rolling n/a Linux kernel: 5.15.6-zen2-1-zen Processor: AMD Ryzen 5 3500U with Radeon Vega Mobile Gfx Cores: 8 Architecture: x86_64 Driver: acpi-cpufreq ------------------------------ Current CPU stats ------------------------------ CPU max frequency: 2100 MHz CPU min frequency: 1400 MHz Core Usage Temperature Frequency CPU0: 11.0% 43 °C 1397 MHz CPU1: 8.2% 43 °C 1397 MHz CPU2: 10.0% 43 °C 1400 MHz CPU3: 13.9% 43 °C 1400 MHz CPU4: 16.2% 43 °C 1400 MHz CPU5: 7.0% 43 °C 1400 MHz CPU6: 13.0% 43 °C 1400 MHz CPU7: 8.9% 43 °C 1400 MHz ---------------------------- CPU frequency scaling ---------------------------- Battery is: discharging Setting to use: "powersave" governor Total CPU usage: 1.2 % Total system load: 0.44 Average temp. of all cores: 42.75 °C Load optimal setting turbo boost: off ------------------------------------------------------------------------------- 果然出问题了,我的笔记本在充电,auto-cpufreq 错误地认为电脑没充电,将调频器设置为 powersave,而且频率只有 1400 MHz。Ryzen 5 3500U 的最高频率可是 3700 MHz 啊。解决办法就是禁用或卸载 auto-cpufreq。 1 2 3 4 # 禁用 sudo systemctl disable --now auto-cpufreq.service # 卸载 sudo pacman -Rsn auto-cpufreq 1.8.0 版本修复了充电检测的问题,但我使用设置充电阈值(charge threshold)之后 auto-cpufreq 会认为笔记本未充电。用了 auto-cpufreq 之后用 Geekbench 跑分比不用还低,TLP 就没这个问题。auto-cpufreq 实在太多问题了,已弃用。 排查问题的时候发现几个好用的工具: TLP:省电利器 cpupower:查看/调节 CPU cpupower-gui:查看/调节 CPU,图形界面 Geekbench:CPU 评测工具,可根据分数检查 CPU 性能

2021/11/29
articleCard.readMore

修复 BitLocker 错误:The system cannot find the file specified

用 BitLocker 给 Windows 10 加密时出现了错误信息:The system cannot find the file specified。这个提示信息简直是废话嘛,为什么不告诉我哪个文件有问题……提示信息还附上了 Win10 安装要求,一样是没用…… 谷歌之后找到了解决办法:把 C:\Windows\System32\Recovery\ReAgent.xml 重命名为 ReAgent.xml.old。

2021/11/9
articleCard.readMore

Arch Linux 备份、加密、还原教程

最近想加密笔记本电脑的硬盘,一般硬盘加密都是在安装系统前做的,但是我的笔记本已经装上 Arch Linux 了。我刚好有个闲置的移动硬盘,于是我就想到了办法: 备份系统到移动硬盘 加密笔记本硬盘 还原系统 重装引导程序 # 待加密的电脑 移动硬盘 刷入 Arch Linux 安装镜像的 U 盘(推荐用 Ventoy 刷入镜像) 网络 备份、还原和写入空数据会花费比较多时间,建议准备 1 天的时间慢慢弄,等待的时候就去干点别的事。请谨慎操作,要是你打错命令(比如:格式化分区时搞错了),可能会丢失数据。可以先在虚拟机练习,弄坏也没关系。用于备份的移动硬盘也加密才是真的安全,为了简化文章,我就忽略这部分了。后面写的加密方法一样适用于移动硬盘。本文适用于 UEFI + GPT。 # 如果你把 EFI 分区挂载到 /efi,那么只需要把引导程序安装到 EFI 分区,Linux 内核不在 /efi,所以不需要占用很多 EFI 分区的空间。但是加密硬盘需要把 EFI 分区挂载到 /boot,Linux 内核也要安装到 EFI 分区,这需要占用更多空间。ArchWiki 建议 EFI 分区至少 260 MiB。我安装了 linux 内核、linux-lts 内核、linux-zen 内核和 GRUB,EFI 分区占用 249.4 MiB。260 MiB 就只能安装 3 个 Linux 内核了。如果有安装多个内核的需求,可以把 EFI 分区调得更大,我自己把 EFI 分区扩大到 3 GiB 了。分区工具可以选择 cfdisk 或 GParted。先缩小 EFI 分区隔壁的分区,再把多出的空间加到 EFI 分区就可以了。 # 启动待备份的 Arch Linux,先查看分区信息,nvme0n1p4 就是需要加密的 / 分区。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 > lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS sda 8:0 0 931.5G 0 disk ├─sda1 8:1 0 350M 0 part /run/media/hunter/B8CA-E0A9 ├─sda2 8:2 0 251.4G 0 part /run/media/hunter/0CB8CBCCB8CBB30E └─sda3 8:3 0 377.9G 0 part /run/media/hunter/6676d81d-215e-4fcc-a1ff-4e87df4ffe34 mmcblk0 179:0 0 116.5G 0 disk ├─mmcblk0p1 179:1 0 116.5G 0 part /run/media/hunter/Ventoy └─mmcblk0p2 179:2 0 32M 0 part nvme0n1 259:0 0 238.5G 0 disk ├─nvme0n1p1 259:1 0 260M 0 part /efi ├─nvme0n1p2 259:2 0 16M 0 part ├─nvme0n1p3 259:3 0 150G 0 part ├─nvme0n1p4 259:4 0 79.4G 0 part / ├─nvme0n1p5 259:5 0 1000M 0 part └─nvme0n1p7 259:6 0 7.8G 0 part [SWAP] 挂载移动硬盘,KDE Plasma 已经帮我自动挂载好了,现在把 nvme0n1p4 备份至 sda3(/run/media/hunter/6676d81d-215e-4fcc-a1ff-4e87df4ffe34)。备份 45G 花了 10 分钟。 1 2 3 sudo rsync --archive --acls --xattrs --hard-links --sparse --one-file-system --delete --delete-excluded --numeric-ids --progress --info=progress2 \ --exclude={"/var/lib/dhcpcd/*","/swapfile","/dev/*","/proc/*","/sys/*","/tmp/*","/run/*","/mnt/*","/media/*","/lost+found"} \ / /run/media/hunter/6676d81d-215e-4fcc-a1ff-4e87df4ffe34 参数含义: --archive --acls --xattrs:保存软链接与文件属性 --hard-links:保存硬链接 --sparse:备份稀疏文件,例如虚拟磁盘、Docker 镜像 --one-file-system:不要备份挂载点 --delete:多次备份时,删除不存在原系统的文件 delete-excluded:多次备份时,删除被排除的文件 --numeric-ids:用数字表示用户组和用户,而不是用名称表示,避免在跨系统使用时出差错 --progress:显示备份文件与进度 --info=progress2:显示总备份进度 --exclude={...}:排除不需要备份的文件 # 备份好就关机,启动 U 盘的 Arch Linux 安装镜像,选择「Copy to RAM」。启动后拔下 U 盘,插入移动硬盘。以下命令可以调大字体、调高亮度: 1 2 3 4 # 调大字体 setfont ter-132n # 调高亮度(把 * 改为实际的目录) echo 200 > /sys/class/backlight/*/brightness 现在开始加密。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 # 写入随机数据,防止原有数据被恢复 # 79.4G 的固态硬盘,时间 5 分 08 秒 cryptsetup open --type plain --key-file /dev/urandom /dev/nvme0n1p4 to_be_wiped dd if=/dev/zero of=/dev/mapper/to_be_wiped bs=1M status=progress # 检查写入数据大小,单位是 Byte blockdev --getsize64 /dev/mapper/to_be_wiped 85298511872 # 85298511872/1024/1024/1024 = 79.44G # 关闭临时容器 cryptsetup close to_be_wiped # 加密分区 cryptsetup --verify-passphrase --verbose luksFormat /dev/nvme0n1p4 cryptsetup open /dev/nvme0n1p4 cryptroot mkfs.ext4 /dev/mapper/cryptroot # 还原还是用一样的 rsync 命令,就是把路径反过来写就行了,先写 sdb3 的挂载点,再写加密分区的挂载点。因为备份的时候排除了不需要的文件,所以不需要 --delete-excluded 和 --exclude={...} 参数。用安装镜像不能方便地复制粘贴命令,我用了简写的命令。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 # 挂载加密分区 mkdir /mnt/cryptroot mount /dev/mapper/cryptroot /mnt/cryptroot # 挂载移动硬盘 mkdir /mnt/disk mount /dev/sdb3 /mnt/disk # 还原系统(注意路径最后的斜杠) # 耗时 15 分钟 rsync -aAXHSx --delete --numeric-ids --progress --info=progress2 \ /mnt/disk/ /mnt/cryptroot/ # 重新挂载 # EFI 分区必须挂载到 /boot,不然开机时无法使用内核 umount /mnt/cryptroot umount /mnt/disk rm -r /mnt/cryptroot rm -r /mnt/disk mount /dev/mapper/cryptroot /mnt mount /dev/nvme0n1p1 /mnt/boot # 创建 swap 文件,大小为 1M*8192(8G) dd if=/dev/zero of=/mnt/swapfile bs=1M count=8192 status=progress chmod 600 /mnt/swapfile mkswap /mnt/swapfile swapon /mnt/swapfile # 重新生成 fstab(file systems table) genfstab -U /mnt > /mnt/etc/fstab # 将根目录 / 改为 /mnt arch-chroot /mnt 编辑 /etc/mkinitcpio.conf,在 HOOKS 这一行加入 encrypt(udev 之后) keyboard(autodetect 之前) keymap(encrypt 之前,如果使用美国键盘布局,可忽略此选项) resume(udev 之后) 完整的内容: 1 HOOKS=(base udev keyboard autodetect keymap modconf block encrypt filesystems resume fsck) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 # 连接无线网络 # 用网线插上就能用了,可以忽略这部分 rfkill list # 检查无线设备状态 rfkill unblock wifi # 如果 WIFI 被禁用就启用 WIFI iwctl # 进入交互式命令行 device list # 列出设备名 station wlan0 scan # 扫描网络 station wlan0 get-networks # 列出网络 station wlan0 connect abcd-wifi # 连接 abcd-wifi exit # 推出 iwd # 重装内核与 microcode # 用 Intel 处理器就安装 intel-ucode # 用 AMD 处理器就安装 amd-ucode # 可能不需要 linux-firmware pacman -Syu linux linux-firmware linux-zen amd-ucode # 重新生成 initramfs mkinitcpio -P 1 2 # 获取 swap_file_offset filefrag -v /swapfile 记下第 1 横行数字的第 4 个数字,18055168。用下面这个好长的命令可以直接获取这个数字。 1 filefrag -v /swapfile | awk '$1=="0:" {print substr($4, 1, length($4)-2)}' 1 2 3 4 # 将 swap_file_offset 插入到 GRUB 配置文件 echo "18055168" >> /etc/default/grub # 将 nvme0n1p4 的 UUID 插入到 GRUB 配置文件 blkid -s UUID -o value /dev/nvme0n1p4 >> /etc/default/grub 编辑 /etc/default/grub,加入 1 2 GRUB_CMDLINE_LINUX="cryptdevice=UUID=uuid-value:cryptroot root=/dev/mapper/cryptroot" GRUB_CMDLINE_LINUX_DEFAULT="resume=/dev/mapper/cryptroot resume_offset=swap_file_offset" 请将 uuid-value 替换为倒数第 1 行的内容,swap_file_offset 替换为倒数第 2 行的内容,删去最后两行。如果你使用了 GRUB 主题并且主题不在 /boot,那就在 GRUB_THEME 前加上 #,硬盘没解密读取不了主题文件。 1 2 3 # 重装 GRUB grub-install --target=x86_64-efi --efi-directory=/boot --bootloader-id=GRUB grub-mkconfig -o /boot/grub/grub.cfg 按下 Ctrl + D 退出 chroot,并执行 reboot 重启。 # 备份、加密和还原完成了,下面是加密后的使用技巧。 # 之前创建了交换分区(swap partition),现在打算改用交换文件(swap file),所以要把删掉交换分区,把多出的空间加到加密分区。本来打算用 cfdisk 扩展加密分区,但是没成功,于是就用带 GUI 的 endeavouros 了。 打开 GParted 右击 /dev/nvme0n1p7 -> Delete 右击 /dev/nvme0n1p4 -> Open Encryption -> 输入密码解锁 右击 /dev/nvme0n1p4 -> Resize/Move -> 把 Maximum size 填入 New Size -> 按下 Enter -> Resize 点击 Edit -> Apply All Operations -> Apply # 1 2 3 4 5 # 复制到 /boot sudo cp -r /usr/share/grub/themes/whitesur-white-1080p /boot/grub/themes # 修改配置文件 echo 'GRUB_THEME="/boot/grub/themes/whitesur-white-1080p/theme.txt"' | sudo tee --append /etc/default/grub sudo grub-mkconfig -o /boot/grub/grub.cfg # 经历了这次加密我才知道可以把整个 Arch Linux 备份下来,那么以后换电脑的时候就不用从头安装系统了。虽然安装 Arch Linux 不是很难(装两三次就熟练了),但是配置还是很花时间,通过备份还原就再也不用全新安装 Arch Linux了,真爽!还原后只需要根据新电脑的硬件做些调整(更换 microcode、显卡驱动等)就行了。定时备份系统到移动硬盘也挺好的,电脑遗失了,买了新的也能很快还原之前的系统。 # 之前用 Windows 的时候,加密硬盘很简单,用 BitLocker 也就是点几个按键就行了。Linux 似乎没有类似的简单易用的工具,所以我用 linux 之后没加密过硬盘。带笔记本出门的时候总担心被偷,然后别人盗取笔记本里面的数据来假扮我…… 电脑遗失是小事,资料被偷是大事。不过想偷我的资料也不是那么容易。我设置了 UEFI 密码,不知道这个密码就没办法启动 U 盘的系统,也就不能读取硬盘了。要么就把笔记本的硬盘拆下来,放到其他的电脑读取,要么重置 UEFI 密码。小偷有这些时间精力不如直接把笔记本卖了。 所以说要偷到我电脑的资料的人一定要有坏心肠、懂电脑软硬件、不怕违法犯罪。我也就是个普通人,花那么大劲偷我的笔记本资料,可谓是吃力不讨好。要偷资料也是偷大人物的嘛。所以我笔记本资料被偷的可能性应该超低吧。 虽然我说服过自己了,但每次带笔记本出门就特焦虑,一开始想象从笔记本被偷,然后马上快进到小偷拿到了我的 SSH 和 GPG 私钥……那我还是加密硬盘吧, 万一我以后成了大人物呢? 这样既安全又能缓解焦虑。 # 这参考资料也就比我的毕业论文少 1 个 :) rsync - Full system backup - ArchWiki dm-crypt/Encrypting an entire system - LUKS on a partition- ArchWiki filesystems - Extend a LUKS encrypted partition to fill disk - Unix & Linux Stack Exchange dm-crypt/Drive preparation - dm-crypt specific methods - ArchWiki Migrate installation to new hardware - Top to bottom - ArchWiki Installation guide - ArchWiki https://medium.com/hacker-toolbelt/arch-install-with-full-disk-encryption-6192e9635281 Arch install with full disk encryption | by Miguel Sampaio da Veiga | Hacker Toolbelt | Medium Swap - Swap file- ArchWiki Arch Linux: 12.2020 ISO Install With Encryption & i3 - YouTube rsync+btrfs+dm-crypt 备份整个系统 - 依云’s Blog Arch Linux 安装使用教程 - ArchTutorial - Arch Linux Studio

2021/10/24
articleCard.readMore

解决 Miix 510-12IKB(Miix 5 Plus)在 Arch Linux 休眠后触控板失效的问题

最近在 Miix 510-12IBK(Miix 5 Plus)上安装了 Arch Linux,它休眠或睡眠后唤醒触控板就失效。我试了好多办法都没用,去官方论坛提问也没人回复。有天偶然发现 KDE Plasma 可以设置触控板开关的快捷键,设置好后遇到触控板失效按快捷键就好了。打开 System Settings 后在这里设置:Workspace -> Shorcuts -> Shorcuts -> System Services -> Touchpad -> Toggle Touchpad。

2021/10/14
articleCard.readMore

以 WPS 为例,手动构建和安装 AUR 的包

更新:安装好旧版后发现最新的 WPS 国际版并没有界面模糊的问题,白折腾了。 1 2 # 安装国际版 WPS yay -Syu wps-office 最近系统从 Kubuntu 切换到 Arch Linux 了,安装了最新的 WPS 国内版,还是遇到了界面模糊的问题。干脆就手动安装旧版的吧。makepkg 不支持 root 帐户,所以要使用非 root 帐户操作。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 # 安装 Git sudo pacman -Syu git # 获取 PKGBUILD git clone https://aur.archlinux.org/wps-office-cn.git cd wps-office-cn # 查看旧版 commit git log # 切换到旧版(11.1.0.10161) git reset --hard c7f6d16d3232488f53755137c58c21736e84f0e6 # 更新系统 sudo pacman -Syu # 安装依赖并打包 makepkg --syncdeps # 简写:makepkg -s # 安装打包好的 WPS,其实就是使用 pacman -U 安装 makepkg --install # 简写:makepkg -i # 上面两条命令可一并写为 makepkg -si

2021/10/11
articleCard.readMore

本地 SSH 连接教程

Secure Shell(安全外壳协议,简称 SSH )是一种加密的网络传输协议,可在不安全的网络中为网络服务提供安全的传输环境。SSH 通过在网络中创建安全隧道来实现 SSH 客户端与服务器之间的连接。SSH 最常见的用途是远程登录系统,人们通常利用 SSH 来传输命令行界面和远程执行命令。 ——Secure Shell - 维基百科,自由的百科全书 本地电脑直接操作就可以了,为什么我还要用 SSH 连接呢?因为这样很酷我懒得从椅子上起来走到另一台电脑操作。本文把被连接的电脑称为服务端,另一台为客户端。开始操作前请确保两台电脑处于同一个网络。 # 在两台电脑安装 OpenSSH 1 sudo pacman -Syu openssh 在服务端启用 SSH 服务 1 2 3 4 5 6 7 8 9 # 启用 sshd.service sudo systemctl start sshd.service # 开机启动 sudo systemctl enable sshd.service # 关闭开机启动 # sudo systemctl disable sshd.service # 关闭 sshd.service # sudo systemctl stop sshd.service 查看状态 1 2 3 4 ❯ systemctl status sshd.service ● sshd.service - OpenSSH Daemon Loaded: loaded (/usr/lib/systemd/system/sshd.service; disabled; vendor preset: disabled) Active: active (running) 显示 Active: active 就说明成功了 查看服务端本地 IP 地址 1 2 ip route get 1.2.3.4 | awk '{print $7}' # 192.168.3.100 用 ip addr 查看也行 客户端连接服务端 1 ssh server@192.168.3.100 # 用 SSH 密钥登陆就可以不输入密码登陆了。 在客户端生成 SSH 密钥 1 2 ssh-keygen -t ed25519 -C "your computer model" # 一直按 Enter 就行 查看并复制 SSH 公钥 1 2 ❯ cat ~/.ssh/id_ed25519.pub ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHY84a2KfbwfkkKyoSvQk+thsKITpmdFzNbYoCs0SlkU magicbook14 连接服务端 1 ssh hunter@192.168.3.100 导入 SSH 公钥 1 2 3 mkdir ~/.ssh touch ~/.ssh/authorized_keys echo 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHY84a2KfbwfkkKyoSvQk+thsKITpmdFzNbYoCs0SlkU magicbook14' >> ~/.ssh/authorized_keys # 禁用密码登陆后别人就不能暴力破解密码了,更加安全。接下来使用服务端操作,用客户端 SSH 连接操作也行。 1 2 # 备份配置 sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak 1 2 # 修改配置 sudo nano /etc/ssh/sshd_config 在里面加入: 1 PasswordAuthentication no 1 2 3 4 # 重启 sshd.service sudo systemctl restart sshd.service # 终止原有连接 pkill sshd # 使用服务端操作,配置并启用 UFW 后只允许特定 IP 访问,例如 192.168.3.177。 1 2 3 4 5 6 # 禁止入站连接(外部访问) sudo ufw default deny incoming # 允许 192.168.3.177 访问 sudo ufw allow from 192.168.3.177 # 终止原有连接 pkill sshd # 1 ss | grep ssh # 1 sudo systemctl stop sshd.service 禁用服务不会终止已有 SSH 连接,要执行以下命令终止所有连接。 1 pkill sshd # # 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 # 查看用户,pts/1 就是 SSH 连接 ❯ w 18:20:06 up 1:08, 2 users, load average: 0.92, 0.54, 0.43 USER TTY LOGIN@ IDLE JCPU PCPU WHAT hunter tty1 17:12 1:08m 53.14s 0.06s /usr/bin/startplasma-x11 hunter pts/1 18:18 14.00s 0.47s 0.47s -zsh # 终止进程 ❯ pkill -9 -t pts/1 # 查看用户,现在没有 SSH 连接了 ❯ w 18:22:23 up 1:10, 1 user, load average: 0.44, 0.48, 0.42 USER TTY LOGIN@ IDLE JCPU PCPU WHAT hunter tty1 17:12 1:10m 58.05s 0.06s /usr/bin/startplasma-x11 # 1 pkill sshd # 11.10 - How can I setup SSH so that it is restricted to my local network? - Ask Ubuntu networking - Connect two computers with SSH in a home LAN - Ask Ubuntu How to kill SSH user sessions - Grepitout How to Kill Inactive or Idle SSH sessions in Linux | 2DayGeek # SSH 教程 - 网道

2021/10/9
articleCard.readMore

给本地电脑配置 UFW(Uncomplicated Firewall)防火墙

安装 # 1 2 3 4 5 6 7 8 9 10 # 安装 UFW 与图形界面 sudo pacman -Syu ufw ufw-extras gufw # 禁止入站连接(外部访问) sudo ufw default deny incoming # 允许出站连接 sudo ufw default allow outgoing # 启用 UFW sudo systemctl enable ufw --now # 检查 UFW 状态,显示 Status: active 就说明成功启用 sudo ufw status verbose # 1 2 3 4 5 6 7 8 9 10 11 # 允许 203.0.113.101 访问 sudo ufw allow from 203.0.113.101 # 开放 8080 端口 sudo ufw allow 8080 # 在规则前加上 delete 表示删除规则 # 取消允许 203.0.113.101 访问 sudo ufw delete allow from 203.0.113.101 # 取消开放 8080 端口 sudo ufw delete allow 8080 # 在服务器使用 UFW 必须先执行 ufw allow ssh(允许 SSH 连接),再执行 ufw default deny incoming,最后执行 ufw enable,不然会导致无法用 SSH 连接服务器。 # Ubuntu Manpage: ufw - program for managing a netfilter firewall Uncomplicated Firewall - ArchWiki UFW Essentials: Common Firewall Rules and Commands | DigitalOcean

2021/10/9
articleCard.readMore

解决 Arch Linux(KDE Plasma)中 Locale LANG=C 的问题

最近在 Arch Linux 上的 Git 显示不了中文,执行了 git config --global core.quotepath false 还是不行。git log 显示的中文变成这样了: 1 Markdown <E6><8A><80><E5><B7><A7><EF><BC><9A>Rmarkdown -> R Markdown 它应该是这样的: 1 Markdown 技巧:Rmarkdown -> R Markdown 查看 locale,发现 locale 居然不是en_US.UTF-8,而是 C,这是啥啊? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ❯ locale LANG=C LC_CTYPE="C" LC_NUMERIC="C" LC_TIME="C" LC_COLLATE="C" LC_MONETARY="C" LC_MESSAGES="C" LC_PAPER="C" LC_NAME="C" LC_ADDRESS="C" LC_TELEPHONE="C" LC_MEASUREMENT="C" LC_IDENTIFICATION="C" LC_ALL= 我之前设置的 locale 明明是 en_US.UTF-8。 1 sudo localectl set-locale LANG=en_US.UTF-8 查阅万能的 ArchWiki 后发现我似乎在 KDE Plasma 把 locale 设置成 Default (C) 了(System Settings -> Regional Settings -> Formats -> Region)。 1 2 3 ❯ cat ~/.config/plasma-localerc [Formats] LANG=C 把 Plasma 的 locale 配置文件删除后重启就行了。 1 rm -i ~/.config/plasma-localerc

2021/10/8
articleCard.readMore

修复 MagicBook 14(Ryzen5 3500U)在 Arch Linux 下亮度突然变 0 的问题

2023 年 3 月 8 日更新:MagicBook 14 在以下内核亮度正常,已经不需要改内核参数了。 linux 6.2.2.arch1-1 linux-lts 6.1.14-1 linux-zen 6.2.2.zen1-1 现在加上参数反而会导致无法调节亮度。如果之前改过内核参数,请删除并重新生成引导程序配置。 我的 MagicBook 14(Ryzen5 3500U)休眠/睡眠/插电/断电/开机后可能亮度降为 0。解决办法:启动时使用以下内核参数。 1 acpi_backlight=vendor 如果你用 GRUB,就修改 /etc/default/grub,在 GRUB_CMDLINE_LINUX_DEFAULT 加上内核参数,如果有多个参数就以空格分开。 1 GRUB_CMDLINE_LINUX_DEFAULT="loglevel=5 acpi_backlight=vendor" 然后刷新配置文件: 1 sudo grub-mkconfig -o /boot/grub/grub.cfg 参考资料:[SOLVED] Failed to start Load/Save Screen Backlight Brightness / Laptop Issues / Arch Linux Forums 延伸阅读:What do the kernel parameters acpi_osi=linux and acpi_backlight=vendor do? - Unix & Linux Stack Exchange

2021/10/6
articleCard.readMore

Arch Linux 安装与配置记录

使用感受 # Arch Linux 用起来太爽了,我已经在主力电脑装上了!软件超多,官方仓库加上 archlinuxcn 仓库 和 AUR,真的是什么都能安装。滚动更新保证软件都是最新版,还不用像 Ubuntu 那样苦苦地等半年更新,也不用准备一大段时间来更新系统,每次用电脑更新一下就行,也就几分钟的事情。ArchWiki 的资料超级全面,我要查的东西里面都有。Arch Linux 平时用起来比 Kubuntu 更快,开机才三四秒,关机也是几秒钟。之前用 Kubuntu 遇到的问题在 Arch Linux 上都没了:关机两三分钟才行、休眠后不会关屏幕、版本更新后要手动修改软件源、KDE Plasma 没有休眠按键。pacman 安装和卸载软件也超快,甩 apt 几条街。AUR 虽然什么软件都有,但都是未经审核的,我还挺担心遇到恶意代码。接下来学学 Bash 和打包软件才行,不然看不懂 AUR 上面的打包脚本。 # 本文多次出现 cat 命令,例如: 1 2 3 4 ❯ cat ~/.xprofile export GTK_IM_MODULE=fcitx export QT_IM_MODULE=fcitx export XMODIFIERS=@im=fcitx 以上命令在本文的意思是创建或修改 ~/.xprofile,并添加 1 2 3 export GTK_IM_MODULE=fcitx export QT_IM_MODULE=fcitx export XMODIFIERS=@im=fcitx Arch Linux 的安装教程有很多,我安装的时候主要看这三份。 Arch Linux 安装使用教程 - ArchTutorial - Arch Linux Studio Installation guide - ArchWiki How To Install Arch Linux 2021 [Step by Step Guide] | ITzGeek 我的电脑用 UEFI 启动,使用三个分区。 /efi / swap EFI 分区本来就有了,跳过创建与格式化 EFI 分区的步骤。创建 / 和 swap 分区即可。感觉用命令行分区好难,我就用 U 盘启动 Kubuntu,用里面的分区软件来分区,用 Windows PE 也行。分区完就可以启动 Arch Linux 安装镜像了,先格式化再挂载。 1 2 3 4 5 6 7 8 9 # 格式化 mkfs.ext4 /dev/nvme0n1p4 mkswp /dev/nvme0n1p5 # 挂载 mount /dev/nvme0n1p4 /mnt # 一定要先挂载 / 再挂载其他 mkdir /mnt/efi mount /dev/nvme0n1p1 /mnt/efi swapon /dev/nvme0n1p5 # # 1 2 3 ❯ cat /etc/pacman.conf [archlinuxcn] Server = https://mirrors.tuna.tsinghua.edu.cn/archlinuxcn/$arch 1 sudo pacman -Syu archlinuxcn-keyring # 1 2 ❯ cat /etc/pacman.conf ParallelDownloads = 16 # 同时下载 16 个包 # Arch Linux 不支持更新部分软件(partial upgrades),所以我使用 pacman -Syu package 命令,先更新所有软件再安装需要的软件。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 # 工具 sudo pacman -Syu trash-cli \ mplayer \ vlc \ flameshot \ spectacle \ obs-studio \ aria2 \ okular \ kdegraphics-mobipocket \ man-db \ gwenview \ os-prober \ pamac-aur \ ufw \ gufw \ ufw-extras \ ntfs-3g \ z \ virtualbox \ virtualbox-guest-iso \ virtualbox-guest-utils \ virtualbox-ext-oracle yay -Syu dropbox \ google-chrome # 美化 sudo pacman -Syu tela-icon-theme-git \ tela-circle-icon-theme-git \ grub-theme-whitesur-white-1080p-git # 编程 sudo pacman -Syu openssh \ nodejs \ npm \ yarn \ webstorm \ webstorm-jre \ rstudio-desktop-git \ android-tools \ tldr \ github-cli \ git # 学习 sudo pacman -Syu goldendict-qt5-git yay -Syu anki-release-source # 安装 ZSH 与插件 sudo pacman -Syu zsh \ oh-my-zsh-git \ zsh-theme-powerlevel10k \ powerline-fonts \ awesome-terminal-fonts \ zsh-syntax-highlighting-git \ zsh-autosuggestions \ zsh-completions-git # 中文字体 sudo pacman -Syu wqy-bitmapfont \ wqy-microhei \ wqy-microhei-lite \ wqy-zenhei \ adobe-source-han-sans-cn-fonts \ adobe-source-han-serif-cn-fonts \ noto-fonts \ noto-fonts-cjk \ noto-fonts-emoji \ noto-fonts-extra # 通讯 sudo pacman -Syu telegram-desktop \ thunderbird yay -Syu wechat-uos \ deepin-wine-tim \ deepin-wine-wechat # Fcitx5 输入法 sudo pacman -Syu fcitx5-im \ fcitx5-chinese-addons \ fcitx5-material-color \ fcitx5-pinyin-zhwiki # 办公软件 # WPS yay -Syu wps-office \ wps-office-mui-zh-cn \ ttf-wps-fonts \ wps-office-fonts # LibreOffice sudo pacman -Syu libreoffice-fresh \ libreoffice-fresh-zh-cn # OnlyOffice sudo pacman -Syu onlyoffice-bin # 杀毒 sudo pacman -Syu clamav clamtk sudo freshclam sudo systemctl enable clamav-freshclam.service --now sudo systemctl enable clamav-daemon.service --now # 杀毒命令 # clamdscan --multiscan --fdpass # 性能增强 yay -Syu auto-cpufreq systemctl enable --now auto-cpufreq sudo pacman -Syu linux-zen linux-zen-headers # 1 2 3 4 5 6 ❯ cat ~/.pam_environment GTK_IM_MODULE DEFAULT=fcitx QT_IM_MODULE DEFAULT=fcitx XMODIFIERS DEFAULT=\@im=fcitx INPUT_METHOD DEFAULT=fcitx SDL_IM_MODULE DEFAULT=fcitx 1 2 3 4 ❯ cat ~/.xprofile export GTK_IM_MODULE=fcitx export QT_IM_MODULE=fcitx export XMODIFIERS=@im=fcitx Fcitx5 的快捷键是 Control + Space,编程软件的补全快捷键也是这个,把 Fcitx5 的快捷键改为 Super + Space 以避免冲突。打开 Fcitx 5 Configuration,点击 Configure global options,把 Trigger Input Method 改为 Super + Space。 # noto-fonts-cjk 包括中文、日文、韩文字体,安装后有时候中文被错误地显示为日文。把中文字体优先级调到日语前面就可以解决这个问题。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 ❯ cat ~/.fonts.conf <?xml version="1.0"?> <!DOCTYPE fontconfig SYSTEM "fonts.dtd"> <fontconfig> <alias> <family>sans-serif</family> <prefer> <family>Noto Sans CJK SC</family> <family>Noto Sans CJK TC</family> <family>Noto Sans CJK JP</family> </prefer> </alias> <alias> <family>monospace</family> <prefer> <family>Noto Sans Mono CJK SC</family> <family>Noto Sans Mono CJK TC</family> <family>Noto Sans Mono CJK JP</family> </prefer> </alias> </fontconfig> 1 2 # 刷新字体缓存 fc-cache -fv 1 2 3 fc-match -s | grep 'Noto Sans CJK' # 如果出现下面内容就代表字体优先级修改成功 # NotoSansCJK-Regular.ttc: "Noto Sans CJK SC" "Regular" # 取消 GRUB 的子菜单,并让它记住上次的启动项。这样选择内核的时候更方便。 编辑配置文件 1 sudo nano /etc/default/grub 把 GRUB_DEFAULT=0 改为 GRUB_DEFAULT=saved 去掉 GRUB_SAVEDEFAULT=true 前面的 # 去掉 GRUB_DISABLE_SUBMENU=y 前面的 # 在 GRUB_CMDLINE_LINUX_DEFAULT= 里加入 nowatchdog,以空格与其他内容分开,加入该参数可加快开关机速度 Ctrl + O 保存,Ctrl + X 退出 更新配置文件 1 sudo grub-mkconfig -o /boot/grub/grub.cfg # 查看 swap 分区名称 1 sudo fdisk -l 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 Disk /dev/nvme0n1: 476.94 GiB, 512110190592 bytes, 1000215216 sectors Disk model: WDC PC SN730 SDBPNTY-512G-1027 Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: gpt Disk identifier: DF3F41B3-00FB-45D1-8B23-3929872B9524 Device Start End Sectors Size Type /dev/nvme0n1p1 2048 206847 204800 100M EFI System /dev/nvme0n1p2 206848 239615 32768 16M Microsoft reserved /dev/nvme0n1p3 239616 168011775 167772160 80G Microsoft basic data /dev/nvme0n1p4 168011776 938358619 770346844 367.3G Linux filesystem /dev/nvme0n1p5 938358784 971902975 33544192 16G Linux swap /dev/nvme0n1p6 971902976 972951551 1048576 512M Windows recovery environment /dev/nvme0n1p7 972951552 998117375 25165824 12G Windows recovery environment /dev/nvme0n1p8 998117376 1000214527 2097152 1G Windows recovery environment /dev/nvme0n1p5 就是 swap 分区。 配置 GRUB 1 sudo nano /etc/default/grub 在 GRUB_CMDLINE_LINUX_DEFAULT 里加入 resume=/dev/nvme0n1p5,以空格与其他内容隔开。修改完就这样 1 GRUB_CMDLINE_LINUX_DEFAULT="loglevel=5 nowatchdog resume=/dev/nvme0n1p5" 更新 GRUB 配置文件 1 sudo grub-mkconfig -o /boot/grub/grub.cfg 重启后生效 1 reboot # 1 2 3 4 5 6 7 8 9 10 11 12 13 # 导入 GPG 私钥 gpg --import armor.asc # 用 GPG 签署 commit gpg --list-secret-keys --keyid-format LONG git config --global user.signingkey FRUR8JBULWM31RFB git config --global commit.gpgsign true # 设置编辑器为 nano git config --global core.editor nano # 显示中文 git config --global core.quotepath false # 设置名称与邮箱 git config --global user.name "Joe" git config --global user.email "joe@example.com" # 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 # 启用 Oh My Zsh cp /usr/share/oh-my-zsh/zshrc ~/.zshrc # 启用 Powerlevel10k 主题 echo 'source /usr/share/zsh-theme-powerlevel10k/powerlevel10k.zsh-theme' >> ~/.zshrc # 启用 zsh-syntax-highlighting(语法高亮) echo 'source /usr/share/zsh/plugins/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh' >> ~/.zshrc # 启用 zsh-autosuggestions(自动提示) echo 'source /usr/share/zsh/plugins/zsh-autosuggestions/zsh-autosuggestions.zsh' >> ~/.zshrc # 启用 zsh-completions-git(自动补全) echo 'fpath=(/usr/share/zsh/site-functions $fpath)' >> ~/.zshrc echo 'autoload -U compinit' >> ~/.zshrc echo 'compinit -i' >> ~/.zshrc rm -f ~/.zcompdump; compinit # 启用 z echo '[[ -r "/usr/share/z/z.sh" ]] && source /usr/share/z/z.sh' >> ~/.zshrc # 把默认 Shell 修改为 ZSH chsh -s /bin/zsh # 进入 zsh zsh # 配置 Powerlevel10k 主题 p10k configure # 配置 gh 补全(需要先安装 github-cli) gh completion -s zsh > ~/_gh sudo mv ~/_gh /usr/share/zsh/site-functions # 配置 yarn 全局安装包的路径 echo 'export PATH="$PATH:$(yarn global bin)"' >> ~/.zshrc # 请看我的这篇教程:给本地电脑配置 UFW(Uncomplicated Firewall)防火墙。 # Moving Thunderbird Data to a New Computer 先把 ~/.thunderbird 文件夹从旧电脑放入网盘,在新电脑打开网盘内的 .thunderbird,把里面的内容复制到新电脑的 ~/.thunderbird,如果有重复文件就选择覆盖。 # https://wiki.archlinux.org/title/GRUB#Detecting_other_operating_systems 安装 Arch Linux 的时候,按照这个教程把 EFI 分区格式化了,结果 Windows 10 的引导文件也没了,头疼。不过用优启通 PE修复了。修复方法:用 U 盘启动优启通,点击「开始菜单 -> 程序 -> 系统安装 -> NTBootAutoFix(引导修复工具)-> 选择 EFI 盘符 -> 开始修复」。优启通网盘下载的速度特慢,想快点修复引导可以去下载微 PE 工具箱,这个下载速度还行,里面也有类似的引导修复工具,不过我没测试过。 接下来用 Arch Linux 把 Windows 启动项添加到 GRUB。 1 sudo pacman -Syu os-prober 加入/取消注释这一行: 1 2 ❯ cat /etc/default/grub GRUB_DISABLE_OS_PROBER=false 1 sudo grub-mkconfig -o /boot/grub/grub.cfg

2021/9/28
articleCard.readMore

解决用笔记本作 OpenWrt 路由器遇到的免密码登陆与屏幕常亮问题

用笔记本电脑作 OpenWrt 路由器有两个问题:不需要密码就登陆、屏幕不会自动关闭,解决办法如下。 # 编辑 /etc/config/system,把 config system 里的 option ttylogin '0' 改为 option ttylogin '1',改完后是这样的: 1 2 3 config system option hostname 'OpenWrt' option ttylogin '1' # 1 2 3 4 opkg update opkg install setterm # 一分钟不动就关屏幕 setterm --blank 1 如果 --blank 选项不行就改成 --powerdown。 # 上大学前(2017 年)买了联想 Miix 510-12IKB(Miix 5 Plus),后来大三的时候开始学编程。Miix 只有 8G 内存,实在是太小了。于是换了台 16G 内存的 Magicbook 14,从此 Miix 就长期处于闲置状态。最近打开几个月没开机的 Miix,屏幕居然多了两条竖线。也不知道是不是之前寄快递的时候压坏了。去查了保修时间,已经过期了。唉,看来还是不修了吧,修还得花钱。可这屏幕的两条竖线看着真不舒服,拿来刷视频都不行了。真为 Miix 的前途感到担忧,难道它年纪轻轻就要退休了吗?思考再三,我决定以后拿它作旁路由。我现在用树莓派 4B 作旁路由,它搭配 500Mbit 宽带使用没问题,和 1000Mb 宽带一起用就性能不足了。日后用上 1000Mb 宽带,Miix 就是树莓派的接班人啦。 接下来就测试一下,我把 OpenWrt 装到 U 盘,用 Miix 启动,确实能用来做旁路由。但有两个问题:不需要密码就登陆、一直开屏幕。免密码登陆不安全,一直开着屏幕费电,而且我担心屏幕一直开着会坏掉。上谷歌用中文和英文搜这两个问题,没有免密码登陆的相关资料。查到了屏幕常亮相关的中文帖子,解决办法居然是把屏幕拆掉或拔掉屏幕排线。嗯……解决不了问题,就解决引起问题的东西,这也不失为一种办法。可这平板电脑看起来就很难拆,拆坏就亏大了,还是别了。最后我去 OpenWrt 论坛问了这两个问题,很快就有热心人士帮忙解决了。原贴: How can I disable auto login on laptop? - Installing and Using OpenWrt - OpenWrt Forum How to turn off the screen of a laptop? - Installing and Using OpenWrt - OpenWrt Forum

2021/9/22
articleCard.readMore

树莓派 4B 超频教程

本文配套文章:在 OpenWrt 控制树莓派 Argon Mini Fan # 树莓派 4B 温度达到 80°C 后 CPU 会降频,超过 85°C 后 CPU 和 GPU 都降频。所以超频前一定要给树莓派 4B 加上散热器以保证温度不超过 80°C。要是超频后达到 80°C 降频就得不偿失了。常见的散热器包括散热片、散热风扇、金属外壳等。我用的是 Argon Neo 和 Argon Mini Fan。用风扇不要到 80°C 才启动,那会都降频了,要在降频前启动,比如超过 60°C 就启动或者一直开着。 充电器电压至少 4.8 V,建议使用树莓派官方充电器或者 5V 3A 充电器。 # 根据树莓派官方杂志的文章,把树莓派 CPU 超频至 2.0GHz。 修改 /boot/config.txt。 1 nano /boot/config.txt 加入以下内容。 1 2 3 # overclock over_voltage=6 arm_freq=2000 重启 1 reboot # 我使用的 SuLingGG/OpenWrt-Mini 固件自带 CPU 频率调节软件,需要进行额外配置。访问 luci 管理界面,点击 「系统 -> CPU 性能优化调节设置」,把「最大 Turbo Boost CPU 频率」调为 2000000。 # 如果超频后无法开机,就把内存卡拔下来插入电脑,修改 /boot/config.txt,把频率调到可以开机。如果实在不行就把添加的超频配置都删了。 # 安装压力测试软件 stress-ng 1 2 opkg update opkg install stress-ng procps-ng-watch 对 CPU 进行压力测试,使其频率达到 2.0GHz 1 stress-ng --cpu 0 开启另一个窗口查看 CPU 频率 1 watch -n 1 vcgencmd measure_clock arm 频率到达 2000000000 左右就对了,按下 Ctrl + C 关闭程序 # 树莓派超频的最高频率是 2.147GHz,但可能会导致树莓派无法重启(我的树莓派就是)。所以建议用 2.0GHz。树莓派可以超频 GPU,但官方人员说作用很小。 Our engineering team told us that the benefits from gpu_freq are marginal at best, and it should be removed if Raspberry Pi 4 fails to boot. —How to overclock Raspberry Pi 4 — The MagPi magazine 如果你要超频 GPU,就在 /boot/config.txt 加上这行代码: 1 gpu_freq=750 这样 GPU 就超频到 750 MHz 了。 加上这行代码后树莓派会一直以最高频率运行,建议别用。 1 force_turbo=1 完整的配置内容是这样的: 1 2 3 4 5 # overclock over_voltage=6 # 增加电压 arm_freq=2000 # CPU 频率,单位是 MHz,最高 2147 # gpu_freq=750 # GPU 频率,单位是 MHz # force_turbo=1 # 以最高频率运行 上述代码只把 CPU 超频至 2.0GHz。# 之后的内容不会被系统读取,换言之,配置前面加上 # 就代表禁用,没有 # 就代表启用。如果不用超频功能,就改成这样: 1 2 3 4 5 # overclock # over_voltage=6 # 增加电压 # arm_freq=2000 # CPU 频率,单位是 MHz,最高 2147 # gpu_freq=750 # GPU 频率,单位是 MHz # force_turbo=1 # 以最高频率运行 修改文件后重启才会生效。 # How to overclock Raspberry Pi 4 — The MagPi magazine

2021/9/20
articleCard.readMore

在 OpenWrt 控制树莓派 Argon Mini Fan

本文配套文章:树莓派 4B 超频教程 本文测试于 SuLingGG/OpenWrt-Mini 固件,系统版本:ImmortalWrt 18.06-SNAPSHOT r0-b0fa0c9 / LuCI openwrt-18.06-k5.4 branch (git-21.247.81448-3061bdd)。 # 把风扇的档位调至 PWM 连接 OpenWrt 1 2 # 请使用你树莓派的 IP,不要照抄我的 ssh root@192.168.1.1 备份配置文件 1 cp /boot/config.txt /boot/config.txt.bak 编辑配置文件 /boot/config.txt 1 nano /boot/config.txt 在底部添加以下内容,树莓派超过 60°C 时风扇就转 1 dtoverlay=gpio-fan,gpiopin=18,temp=60000 # 单位是 1/1000°C 按下 Ctrl + O 保存,Ctrl + X 退出 安装插件 1 2 opkg update opkg install kmod-hwmon-core kmod-hwmon-gpiofan kmod-i2c-core 重启 1 reboot 如果要修改温度就改动 /boot/config.txt 再重启 1 2 nano /boot/config.txt reboot # 安装压力测试软件 stress-ng 1 2 opkg update opkg install stress-ng procps-ng-watch 对 CPU 进行压力测试,使其超过 60°C 1 stress-ng --cpu 0 开启另一个窗口监控温度 1 watch -n 1 vcgencmd measure_temp 超过 60°C 后看看风扇转不转,如果转了就按下 Ctrl + C 关闭程序。温度下降后再看看风扇转不转,不转就对了 # Argon Neo 搭配 Argon Mini Fan 真好用啊!调好风扇之后树莓派就可以做一个安静的路由器了,只有温度过高时风扇才转。要是你的树莓派也用 OpenWrt,不要用 Argon Fan HAT。OpenWrt 不能安装 Argon Fan HAT 的控制脚本,装上风扇后它只会以 50% 的转速一直转。 # 这是 SuLingGG/OpenWrt-Mini 固件 /boot/config.txt 的内容。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 ################################################################################ # Bootloader configuration - config.txt ################################################################################ ################################################################################ # For overclocking and various other settings, see: # https://www.raspberrypi.org/documentation/configuration/config-txt/README.md ################################################################################ # OpenWrt config include distroconfig.txt [pi2] dtparam=i2c_arm=on,audio=on [pi3] dtparam=i2c_arm=on,audio=on [pi4] dtparam=i2c_arm=on,audio=on [all] # Place your custom settings here. dtparam=i2c_arm=on,audio=on # Official Raspberry Pi 4 fan? (Yes!, instructions inside) - Hardware Questions and Recommendations - OpenWrt Forum [4:23] The Best $10 Pi4 Case Fan Combo - The Argon Poly+ - YouTube

2021/9/15
articleCard.readMore

树莓派 4B OpenWrt 旁路由教程

2022-12-04 更新 # 现在树莓派的价格贵得离谱,性价比很低。如果你还没买,建议你别买。如果你已持有树莓派,建议去闲鱼卖了,换成玩法更多、性能更强的 X86 软路由/迷你主机。我 2019 年 10 月买的树莓派 4B 4GB 内存版价格是 462 元,现在同一家店卖 1098 元。我在闲鱼以 950 元卖掉了树莓派 4B 4GB(含外壳、风扇、电源、HDMI 线、内存卡),买了 1095 元的零刻 EQ59(N5105、16GB RAM、500GB SSD)。EQ59 性能远超树莓派 4B,我在 EQ59 装了 Proxmox VE,可以装多个虚拟机,用途更多,比树莓派好用多了。 # 本文内容主要来自 SuLingGG 的 OpenWrt-Rpi 文档,感谢 SuLingGG 编译的 OpenWrt 并写了详细的文档。我的吃灰派树莓派 4B 在墓里躺了近两年,又复活了。欢迎大家捐赠 SuLingGG 编译的 OpenWrt。如果本文太难懂,请到 Youtube 或者哔哩哔哩搜索「树莓派安装 OpenWrt」和「树莓派 旁路由」,看看教程视频了解过程。然后关闭这篇教程再回来看本文。本文主要内容为安装 OpenWrt 固件、旁路由(旁路网关)设置、后续设置(扩充容量、关闭电源灯……)。 请看 SuLingGG 的文档: 自编译 OpenWrt 系列 - 固件特性 | 美丽应用 内置功能 · SuLingGG/OpenWrt-Rpi Wiki # 刷入固件前先准备好作案工具: 选择一个网站下载 SuLingGG 编译的 Lean OpenWrt 固件:openwrt.cc、Google Drive Google Drive 的下载位置如下,请选择日期最新的固件,如果最新日期没有树莓派 4B 的固件就看看之前的 1 2 3 4 5 6 7 8 firmware ├── 2021-08-26 ├── 2021-08-27 ├── 2021-08-28 └── ... └── lean # Lean 版固件 └── bcm27xx # Lean 版树莓派系列固件 └── bcm2711 # 适用于树莓派 4B (64位) 下载文件名包含 ext4-factory 或 squashfs-factory 的文件,例如 openwrt-bcm27xx-bcm2711-rpi-4-ext4-factory.img.gz。squashfs 重置系统更方便,ext4 固件扩充容量更简单。下文以 ext4 固件为例。固件版本的区别请看这里 解压文件,获得 openwrt-bcm27xx-bcm2711-rpi-4-ext4-factory.img 安装 balenaEtcher microSD(TF1)卡(固件大概 1G,建议闪存卡2至少 4G) microSD(TF)读卡器(建议买 USB3.0 版,速度更快) 删除闪存卡所有分区,格式化为 fat32(不格式化可能导致无法保存设置) 1 条千兆网线 电脑(带网口的更好) SSH 客户端(可忽略) 准备完毕,现在开始刷入固件: 把闪存卡插入读卡器,读卡器插入电脑 打开 balenaEtcher 点击「Flash from file」 选择解压好的「openwrt-bcm27xx-bcm2711-rpi-4-ext4-factory.img」 点击「Select target」,选择闪存卡,注意看容量对不对,请勿选择本机硬盘 点击「Flash!」 成功后把闪存卡插入树莓派,树莓派插电后红灯常亮表示正常 # 路由器默认 IP 是 192.168.1.1,用户为 root,密码为 password。如果操作中出现问题导致无法继续配置,请重新刷入固件。 # 选择一种连接树莓派的方式: 断开树莓派的有线连接,电脑连接树莓派发射的 WIFI:OpenWrt 断开电脑的无线连接,用网线接入树莓派 # 为了防止别人连上 WIFI 捣蛋,先修改 WIFI 密码。 点击「网络 -> 无线 -> 修改」 点击「基本设置」,在「ESSID」填入 WIFI 名称 点击「无线安全」,在「密码」填入新密码 点击「保存&应用」 # 我的路由器管理界面地址为 192.168.0.1,接下来要把树莓派的 IP 改为与路由器同一网段,即 192.168.0.x(0≤x≤255)。这里我把树莓派 LAN 口 IP 设置为 192.168.0.100。为了避免冲突,不要把树莓派 LAN 口 IP 最后一段设置成 0/1/255。请根据情况设置,不要照搬我的 IP。如果你的路由器管理界面为 192.168.31.1,那你可以把 IP 设置为 192.168.31.100。更改 IP 后请记好,以后管理界面都在 192.168.0.100。设置前在电脑可以打开终端(CMD 或 Powershell )检查是否冲突: 1 ping 192.168.0.100 如果显示「Destination Host Unreachable」就代表地址没被占用。如果没问题就选择一种设置方式将 LAN 口 IP 改为 192.168.0.100: 打开终端执行命令: 1 2 3 4 ssh root@192.168.1.1 # 密码是 password uci set network.lan.ipaddr=192.168.0.100 uci commit network /etc/init.d/network restart 用浏览器访问 http://192.168.1.1/,用户名为 root,密码为 password,手动设置: 点击「网络 -> 接口 -> LAN -> 修改」 IPv4 地址改为 192.168.0.100 点击「保存&应用」 设置好后重新连接树莓派网络。 # 登陆 http://192.168.0.100/ 点击「网络 -> 接口 -> LAN -> 修改」 协议:静态地址 IPV4 地址:192.168.0.100(之前修改过,现在保持不变) IPv4 子网掩码: 255.255.255.0 IPv4 网关:改为上级路由器管理界面 IP:192.168.0.1 Pv4 广播:把上级路由网段 IP 最后一段改为 255: 192.168.0.255 使用自定义的 DNS 服务器:同样为上级路由器 IP:192.168.0.1 忽略此接口/不在此接口提供 DHCP 服务 (在页面底部):打勾 点击「保存&应用」 # 断开电脑与树莓派的连接,用网线将树莓派接到路由器 LAN 口。 # 连接主路由的设备需要进行以下设置: IP 获取方式改为 「静态(或手动)」 IP 地址:填为路由器网段下任意不冲突的 IP (不能与已分配的 IP 冲突,IP 最后一段也不可为 0/1/255),以上文为例,可设置为 192.168.0.166 前缀长度/子网掩码:若提示填写前缀长度,则填写 24,若提示填写子网掩码,则填写 255.255.255.0 DNS:填写为树莓派 LAN 口 IP:192.168.0.100 网关/路由器:填写为树莓派 LAN 口 IP:192.168.0.100 其他设置保持默认即可 # 建议修改管理员密码,其余设置按需调整。 # 固件只使用闪存卡 1G 左右的空间,剩下的空间就闲置了。我前面刷入了 ext4 固件,使用 Linux 系统的 GParted 调整 rootfs 分区即可扩充空间。rootfs 分区前后至少留出 4M 的空间3。详细教程:SD 卡分区扩容指南 | 美丽应用。 # 点击「系统 -> 管理权」 在「密码」和「确认密码」处填入管理员密码 在「SSH 密钥」处填写公钥后可以 SSH 免密码连接 点击「保存&应用」 # 红色电源灯看着不舒服,于是我就关掉了。 点击「系统 -> LED 配置」,使用两个配置。 配置 1 软件:led0 LED 名称:led0 默认状态:不打勾 触发器:无 配置 2 软件:led1 LED 名称:led1 默认状态:不打勾 触发器:无 # 我的树莓派刷入系统网络后没问题,但还是引用一下旁路由设置指南的内容,留给需要的人。 如果你的上级路由固件为 老毛子 Pandavan,树莓派做旁路由出现卡顿情况的话,请尝试关闭 Wan 口设置中的 “IPv4 硬件加速” 如果你严格按照此文章操作,但出现 无法上网、访问国内网站缓慢 等症状,可在完成上文全部步骤的基础上,在“网络 - 防火墙 - 自定义规则”中新增一行 iptables 规则并重启防火墙再试: 1 iptables -t nat -I POSTROUTING -j MASQUERADE 若仍未解决,可以尝试删除原有两条规则并重启防火墙再试: 1 2 iptables -t nat -A PREROUTING -p udp --dport 53 -j REDIRECT --to-ports 53 iptables -t nat -A PREROUTING -p tcp --dport 53 -j REDIRECT --to-ports 53 如果以上两个方法未能解决,请尝试在 Lan 口的“物理设置”中取消“桥接接口”的打勾,并在下方的“接口”中选择“eth0”,保存并应用再试。但请注意,此时树莓派的板载无线网卡将无法使用 (有信号但无法上网)。 本篇文章所述设置方法可能对某些型号的华为路由器无效,建议更换其他路由器再试。 # 超频后性能更强,相关教程请看我写的两篇博客。 在 OpenWrt 控制树莓派 Argon Mini Fan 树莓派 4B 超频教程 # # 通过 WIFI 或网线连接树莓派,手动把 IP 设置为 192.168.0.100 的同一网段,即 192.168.0.x(0≤x≤255,x≠100),例如 192.168.0.1。此时就能连接,可以用浏览器进入管理界面 192.168.0.100 了。 # 先把 microSD 卡插入 Linux 电脑,然后打开终端执行命令。 1 2 3 4 5 6 7 8 9 10 11 12 13 # 查看分区 # user 为你的用户名 ls /media/user # 11cd116c-beae-43ae-bfb5-b8ec18c9b98a boot disk # 进入分区 # 请根据情况输入分区名称 cd /media/user/11cd116c-beae-43ae-bfb5-b8ec18c9b98a # 查看 ip grep "ipaddr" ./upper/etc/config/network # option ipaddr '127.0.0.1' # option ipaddr '192.168.0.100' 输出结果里的 192.168.0.100 就是 IP 树莓派地址。如果你不会用 Linux 就重新刷固件吧。 # 请使用 OpenWrt-Rpi 的姊妹版 OpenWrt-Mini,点击这里下载,安装方法和 OpenWrt-Rpi 一样。 # SuLingGG/OpenWrt-Rpi: Raspberry Pi & NanoPi R2S/R4S & G-Dock & x86 OpenWrt Compile Project. (Based on Github Action / Daily Update) 自编译 OpenWrt 系列 - 旁路由设置指南 | 美丽应用 自编译 OpenWrt 系列 - SD 卡分区扩容指南 | 美丽应用 关闭树莓派的指示灯 · Issue #150 · SuLingGG/OpenWrt-Rpi microSD 才是正确的名称,但它常被误称为 TF 卡。两者的关系如下(摘录自维基百科):microSD卡原本称为TF卡(T-Flash卡或TransFlash),由摩托罗拉与闪迪共同研发,在2004年推出。不过闪迪无法自行将它推广普及化,前期仅有摩托罗拉的手机支持TransFlash。为了能将销路完全拓展,闪迪于是将TransFlash规格并入SD协会,成为SD家族产品之一,造就了目前使用最广泛的手机存储卡。 ↩︎ microSD 是闪存(flash memory)卡,而不是内存(RAM,Random Access Memory)卡,但「内存卡」的说法更广泛。 ↩︎ 「rootfs 分区前后至少留出 4M 的空间」的说法是在这里看到的,其实我也不知道为什么要留出 4M 空间。如果你知道,请告诉我。 ↩︎

2021/8/30
articleCard.readMore

第一次租国外的服务器

最近想租个服务器玩玩,因为我讨厌手机号注册和提交身份信息,就不考虑国内厂商了。之前在知乎好几次看到有人推荐 Vultr,那就试试看吧。注册好就用 Paypal 充了 10 美元,结果就倒霉了。Vultr 提示我帐号审核可能要 24 小时。 Vultr 的帐号客服只在周一至周五的白天1上班,而且 Vultr 采用美国东部时间,比北京时间慢 12 小时。我这边晚上 9 点的时候,对面的客服才刚上班。没有即时聊天,只能发工单,以下是艰难的验证过程(时间为北京时间)。 # # 注册并用 Paypal 充值 10 美元。 # 收到通知说需要提供身份证和信用卡照片来验证帐号。身份证只需要显示姓名和照片,信用卡只需显示姓名和后四位。 The following will be required to complete the form for verification sufficiently: A photo of your government ID (showing a name and photo only) and A partial photo of the credit card linked to the account (showing the last four numbers & name only). 注意,要抹掉信用卡安全码,不然有被盗用的风险。 # 我问客服审核后会不会销毁照片。 How do you deal with the photos after verification? Will it be destroyed? # # 客服说审核后会删除照片。 This is currently our vetting process but, rest assured, all electronic copies will be deleted after review and you may cover any pertinent information you deem sensitive. # 提交身份证和信用卡照片。身份证只有姓名和号码没涂抹。信用卡抹掉安全码和号码前面部分,只留下后 4 位,其他位置未涂抹。 # 客服说要拍到身份证的照片才行。 # 补发带照片的身份证。 # 客服说要手持身份证和脸一块拍照。 We were unable to validate some of the information provided. To help this process along, please provide the following: A photo of you holding the recently uploaded ID (next to face) 我吐了,怎么不早说。前面白搞了,又得等了。 # 上传手持身份证的照片,身份证只有姓名、号码、和照片没涂抹。 # # 认证还没行,客服询问我公司名称和服务器的用途。 We appreciate the information provided however, we need more information to validate your intended usage. Please describe in as much detail as possible what you intend to do with your instances and provide the business name and organization URL(s) under which you offer services. # 真是无语了,买个服务器也问东问西的,而且我都没有公司。就说买服务器用来学 Linux,也可能搭建个人网站。 I don’t own or belong to any business. I want to use remote servers to learn linux distros. I also want to build personal websites via servers. # 认证还没行。客服认为我有多个帐号,说一人应该只用一个帐号,请我解释解释。 It appears you have multiple accounts with us. The system generally only allows one account per customer, can you please clarify why you need multiple accounts with us? # 我又吐了,我第一次注册,哪来的多帐号。 Oh, no. I have and use only one account. # # 客服说搞定了。 Thank you for providing the requested information. I have finalized your account authorization at this time. I appreciate your patience regarding this matter. # 没想到在 Vultr 买个服务器居然用了 4 天,真的吐血了。隔着 12 个小时联系真困难。第三天(8 月 11 号)都要气死了,把玩服务器的热情都耗尽了2,然后试了 Linode。用 Linode 倒是挺顺利的,注册完用银联信用卡作为支付方式,马上就能用了。早知道之前在 Vultr 申请退款算了。罢了罢了,就当是练英语吧。 我试了以下服务器:Vultr 的东京(Tkoyo),Linode 的东京、新加坡(Singapore)。在本地机器 SSH 连接过去,打字都卡,用科学上网也一样。用 Mosh 连接就好多了,但是要使用 tmux 才能滚动终端,最后发现用 Visual Studio Code 的Remote - SSH 插件连接延迟更低,也能滚动终端,还能处理服务器文件(上传、下载、编辑),十分好用。 # Vultr 和 Linode 都是按小时计费,每月 1 号扣钱。服务器关机占坑也会扣钱,删除才不扣钱。如果 Vultr 帐号有余额,那删除就会马上扣钱。Vultr 只有纽约(New York)有 2.5 美元/月和 3.5 美元/月的服务器,其余地区最便宜是 5 美元/月。Linode 最便宜是 5 美元/月。 Vultr 注册完就叫我充值,还有信用卡充值多少就送多少的优惠。看到这优惠就想充 100 美元,差点就中招了。还好只充了 10 美元。Linode 就比 Vultr 实在多了。Linode 一开始就绑定信用卡,不会叫人充值,用多少就扣多少钱。现在 Vultr 那边充了 10 美元还没怎么用,感觉有点浪费。还是用信用卡好,用多少就扣多少钱。 Vultr 和 Linode 都有注册用余额的活动,在谷歌搜「Vultr coupon」和「Linode coupon」就能找到了,通过 Vultr 和 Linode 用户的邀请链接注册也有优惠。后来我又注册了 DigitalOcean,注册后用优惠券白拿了 15 美元。DigitalOcean 和前面两家厂商也差不多,都是按小时计费,最便宜的服务器也是 5 美元/月。但 DigitalOcean 的帐单不是实时更新,一日更新一次。 如果你想注册 Vultr 或 DigitalOcean,可以试试我的邀请链接,注册后会有余额奖励。 我记得是早上 9 点到下午 6 点,查了一下时间,但没查到,也懒得找了。 ↩︎ 我第一次搭建网站的时候以为一定要备案,经历了曲折的过程后就丧失热情了。看来热情等着等着就会耗尽啊。 ↩︎

2021/8/10
articleCard.readMore

在 Debian/Ubuntu 安装旧版 WPS Linux

最近把 WPS For Linux 更新到最新的 11.1.0.10702,打开就提示「系统DPI不对称,WPS可能存在显示问题」,果然 WPS 都是模糊的。打算去官网找上个版本,结果只有最新版,气死我了!在谷歌搜了几次也找不到历史版本。随后我在万能的 AUR(Arch User Repository)找到了 WPS,这里有旧版的下载链接。以下是下载与安装步骤: 点击页面的 View Changes 在 Commit message 这里找到上个版本 11.1.0.10161 点击 upgpkg: wps-office-cn 11.1.0.10161 搜索 source_x86_64 = ,找到 + 开头的绿色文本,https://wdl1.cache.wps.cn/wps/download/ep/Linux2019/10161/wps-office_11.1.0.10161_amd64.deb 就是我们要的下载地址 安装后要删除配置才能用 1 2 3 4 5 6 # 下载 wget https://wdl1.cache.wps.cn/wps/download/ep/Linux2019/10161/wps-office_11.1.0.10161_amd64.deb # 安装 sudo apt install ./wps-office_11.1.0.10161_amd64.deb # 删除配置文件 rm -rI /home/hunter/.config/Kingsoft/ 后记:我从未用过 Arch Linux,我一开始把仓库克隆下载就查看 PKGBUILD 文件,歪打误撞地得到了下载地址。后来才发现下载地址就在 .SRCINFO 文件,之前真的白费力气了。突然感觉 Arch Linux 真的是啥软件都有人打包,连 UOS 独占的微信都有,搞得我都想从 Kubuntu 换过去了。Ubuntu 半年才更新一次,每次更新完都要手动处理软件源,实在是烦。Arch Linux 这种滚动更新的 Linux 发行版对我来说很有吸引力,有空的时候要试试。 以下是先前惨痛的尝试。 这有个 Git 仓库,里面的 PKGBUILD 就是安装脚本。在里面能找到旧版的下载链接。 克隆仓库到本地。 1 2 3 4 git clone https://aur.archlinux.org/wps-office-cn.git cd wps-office-cn git log --pretty=oneline --graph --abbrev-commit git reset --hard c7f6d16 现在看到上个版本 11.1.0.10161 对应的提交是 c7f6d16,回退到这个版本。 1 2 3 4 5 6 7 git reset --hard c7f6d16 grep "pkgver=" PKGBUILD # 查看版本号,版本号为 11.1.0.10161 grep "source_x86_64=" PKGBUILD # 查看下载网址,网址为 https://wdl1.cache.wps.cn/wps/download/ep/Linux2019/${pkgver##*.}/wps-office_${pkgver}_amd64.deb # ARM 设备的应该用下面这条命令 # grep "source_aarch64" PKGBUILD # ARM 版的网址为 https://wdl1.cache.wps.cn/wps/download/ep/Linux2019/${pkgver##*.}/wps-office_${pkgver}_arm64.deb 把下载网址(https://wdl1.cache.wps.cn/wps/download/ep/Linux2019/${pkgver##*.}/wps-office_${pkgver}_amd64.deb)的 ${pkgver##*.} 替换为版本号的最后一串数字(10161),把 ${pkgver} 替换为版本号(11.1.0.10161),最后获得的网址就是 WPS 11.1.0.10161 的下载网址:https://wdl1.cache.wps.cn/wps/download/ep/Linux2019/10161/wps-office_11.1.0.10161_amd64.deb。现在就可以下载安装,安装完后要删除配置文件才能运行。 1 2 3 4 5 6 # 下载 wget https://wdl1.cache.wps.cn/wps/download/ep/Linux2019/10161/wps-office_11.1.0.10161_amd64.deb # 安装 sudo apt install ./wps-office_11.1.0.10161_amd64.deb # 删除配置文件 rm -rI /home/hunter/.config/Kingsoft/ 如果你想安装其他版本,不用重复我前面的步骤。在这里找你想要的版本,把版本号替换到我前面找到的网址就行了,这个网址一直没变过。要是不行就从头做起吧。

2021/8/8
articleCard.readMore

用笔记本电脑屏幕玩 Nintendo Switch

缘起 # 我从去年末尾开始玩健身环大冒险,没毕业前在出租屋自己一个人玩。毕业后回家都是在客厅玩,要是有人在场我就不好意思了,于是有时候训练计划就被打断了。前些天和女朋友去广州把出租屋的行李都寄回家,出门带了NS(Nintendo Switch)和笔记本电脑。收拾完东西和女朋友玩马力欧赛车,已经打包好显示器了,就只能看着 NS 的屏幕玩。两个人都看得眼睛累死了,女朋友就问我能不能把 NS 接到笔记本电脑上玩。我说:「能,买个采集卡。便宜的也得四五百吧,感觉不便宜。」一般笔记本电脑的 HDMI 只能输出信号,不能输入信号,所以直接接上是接收不到 NS 画面的。 我以为采集卡都是四五百起步,去淘宝看,还是有便宜的啊,买了 87 块的绿巨人采集卡,型号是 LJN-CJQ002。正好可以解决玩健身环的问题。除了健身环外,分级比较高的游戏也不太适合在客厅玩,比如 AI 梦境档案。上次我在客厅玩的时候突然来了这样一句台词: 总感觉在客厅怪尴尬的,赶紧按下主页键退出。只要我按得快,就没人注意到。 # 在官网下载并安装 OBS1 Studio 打开 OBS,进入自动配置 选择 Optimize just for recording Base(Canvas) Resolution = 电脑的分辨率 FPS = 60 Apply Settings 接线:Nintendo Switch(NS) -> 底座 -> HDMI 线 -> 采集卡 -> 电脑 给 NS 和电脑插电2 设置视频信号 点击 OBS 下方 Source 的 + 按钮 Video Capture Device -> Create new -> OK Device = 带 USB 名称的 Video Format = 先试试默认的,不行就换,我用的设备用不了 YUYV 格式,其他格式都行 Resolution = 电脑分辨率 Frame Rate = 60 FPS OK 在画面空白处右击,勾上 Enable Preview 设置音频信号 点击 OBS 下方「Audio Mixer -> Mic/Aux」右下角的齿轮按钮 Advanced Audio Properties Mic/Aux -> Audio Monitoring -> Monitor Only (mute output) Close 如果这个办法不行,就在 Source 添加 Audio Input Capture,然后用上面的步骤设置 放大预览画面 右击预览画面 勾上「lock preview」 右击预览画面 Preview Scaling -> Canvas 点击菜单栏的 View 取消所有勾上的选项,包括 Docks 里面的 View -> Fullscreen Interface(F11),按下 F11 退出全屏 如果需要恢复默认界面,就点击 View -> Docks -> Reset UI,然后再勾上之前的选项 # 感觉玩游戏的时候帧率只有三四十,达不到产品页说的 60 帧。玩马力欧赛车卡得影响发挥,玩健身环还行,梦境档案没问题,Youtube 能播放 1080P 60FPS 的视频。问客服:「帧率低怎么回事?和采集卡配置或笔记本配置有关系吗?」客服说:「没有配置要求,有独立显卡更流畅。」我的笔记本是 Magicbook 14(AMD Ryzen 5 3500U ,16G RAM),用女朋友的小新 Air 14(AMD Ryzen 5 4600U,16G RAM)感觉更流畅。要是不需要省钱、录屏、直播,还是买便携式显示器比较好。最后还有一些待解决的问题: 如何查看实时帧率 默认的全屏预览只能 720p,如何调成 1080P 全屏后如何隐藏光标 OBS 的全称是 Open Broadcaster Software。 ↩︎ 笔记本电脑不插电会变慢。 ↩︎

2021/8/5
articleCard.readMore

解锁 Twitter 帐号

Twitter 也太坑了,我刚注册完,一登陆就锁定我帐号。联系客服解锁一个月后又锁定了。解锁要我验证手机号,可中国手机号也收不到验证码。罢了,反正我也不想绑定手机号。还是照旧发邮件让客服解锁。点击 Contact Us 里的 Locked and suspend account issues 就可以联系客服了,在 Description of problem 填入以下内容: Dear Sir or Madam. My account was locked, but I did not violate the Twitter Rules at all. I just tweeted several times and followed one account. I can not use China phone number to verify because it can not receive confirmation code. Please help me to unlock my account. This account was locked second time. Could you tell me why my account was locked twice. Thank you in advance. 然后马上就收到自动回复说我违反了 Twitter 规则: We’re writing to let you know that your account has been flagged for unusual behavior that violates the Twitter Rules, and has been locked until you take the following steps… 我看了规则内容,我也只是正常使用,并未违反规则。此时要再申诉一次,还是填原来的内容。这次才收到回复说会继续审核申诉: Thanks for your report. It looks like this is connected with your original case # 16409264056, so we’ve added it to that first report. We’ll continue our review with this information. 我的申诉内容除去客套话,真正有效的部分应该是这些: My account was locked, but I did not violate the Twitter Rules at all. I can not use China phone number to verify because it can not receive confirmation code. Please help me to unlock my account. 也许第二句也可以省略掉: My account was locked, but I did not violate the Twitter Rules at all. Please help me to unlock my account. 如果你也遇到了一样的问题,可以试试发这些内容,可根据自己情况作改动。

2021/7/25
articleCard.readMore

被微信绑架

我大学基本上都是用微信处理学校的事务,比如收通知、联系老师。唯一的例外是收作业,基本上作业都是用电子邮件交,不过也有用微信的。在大学用微信办公 4 年了,我真的是气到吐血。微信本来是个聊天软件,微信办公,什么狗屁玩意。我必须要好好吐槽一番滥用微信的现象。 上大学加了超多群,这就是噩梦的开始。以下是我加的群: 学院与专业 学院群(聊天、通知) 专业聊天群 专业通知群 班级 班级通知群 班级作业通知群 班级聊天群 课程 几乎每门课一个微信群/QQ群(至少加了二三十个) 一个通知可以从学院群出现,然后传到专业聊天群、专业通知群、班级聊天群、班级通知群。为什么同一条通知我要看好几次,我的时间很宝贵好吧。更恶心的是,微信不能修改发出的信息。微信交流成本太低了,动动手指就能发信息。微信发通知的人经常不好好写,发出了有错的通知,然后又发一次修正内容,这条内容又在好几个群跳动。所以每位同学都要看一次带错误的通知,又看一次修正内容。年轻人的大好青春,怎么就浪费在这了。搞个网站发通知多好啊,错了就修正,同学看到的永远是最新版,还能用 RSS 订阅。微信就用来提醒大家去看就行了。再不济发邮件也好啊。 本来聊天群和通知群就是各司其职,但是发通知的人有时候就在聊天群发通知,后面的人聊着聊着,通知就淹没了。有同学去问发通知的人一些问题,他就不耐烦,说之前发过了。100 条信息里面藏了 1 条通知,我根本不想看大家聊天好吧。虽然我很讨厌去聊天群检查通知,但是我已经被迫成了熟练的聊天群通知打捞员。不仅聊天群干兼职,通知群也干兼职。从大四开始,辅导员为了刷就业率,成天在通知群发招聘信息。从此通知群沦陷了,充斥着该死的招聘广告,恶心程度和电梯广告有得一比。我真的是宁愿去聊天群打捞通知。我现在巴不得时光倒退到没有手机电脑的时代,把通知贴到宿舍楼下得了。要是口口相传就更好了,交流成本高了人就会好好说话。 微信办公会模糊生活和工作的界限。本来我只是拿微信来聊天的,结果上大学加了一堆群和好友,真的不是说删就删啊。有时候我只想看朋友的信息,不想看学校的信息。但是打开微信就是全部信息都混杂在一起,即使人不在学校,打开微信一看,感觉自己还在上学。要是专门建一个工作号区分生活和工作就好多了,不过刚上大学那时完全想不到微信办公那么恶心。我现在已经注册了工作专用的微信号,下次不用受那么多苦了。 微信和部分微信用户还有很多恶心的地方: 被拉进群不需要同意,人人都可以拉你进广告群 不能屏蔽群信息,收到信息永远有红点 群要自己保存,不然找不到 不能云同步聊天记录 2021 年了,什么聊天软件不同步聊天记录?!我电子设备就只有一台手机吗?!而且每次换手机的时候迁移聊天记录都很烦! 收到的文件不下载,7 天后就没了 当我打开资料发现被清空的时候,我吐了。 没有官方 Linux 版1,网页版也没了 语音没进度条,不能调速 听一半切换应用,回来再重头听,气死人。 被人删好友,对方还躺在我的好友列表。 喂,删了我就从列表里消失啊,发信息的时候发现被删就挺难过。 小程序:腾讯制造的浏览器 公众号:封闭的世界 只能用搜狗查公众号文章,评论需要被审核才发出来,不能回复某条评论。 朋友圈:广告圈 一堆点赞 xx 个免费获得 yy 的动态。现在毕业了有同学在朋友圈发公司的招聘信息,喂,你好好上班不行吗,发招聘信息免费加班吗?还有那些拉票的,我看到就投给竞争对手。 电脑登录需要手机,不能用密码。 微信密码是摆设吗?不能用来登陆? 即使没有微信办公那些屁事,我也不喜欢用微信这样即时通讯软件与人交流。微信交流前要先加好友,有些人我都不认识,为什么要一开始就建立一个关系呢?有些人只是和我谈一两件事,但还是得加好友才能开始谈,我感觉谈完了好像就没有再联系的必要。要是我不删除好友,我的好友列表就要不断膨胀了。我觉得删除好友很残忍,显得我很无情。要是有人给我发信息的时候发现被我删了,也不知道他怎么想我。有些人加我好友的时候也不说明一下,我都不知道是干嘛的,就更不想加了。我不喜欢一开始就建立关系,所以最近一两年几乎没加过新的好友。加我好友的也大多被我拒绝或者忽略了。 微信未读信息的小红点让我很焦虑,仿佛不赶紧回复不行。有些人发的信息不知所云,我压根不想回复。但是碍于好友这层关系,我还是回复了。最近半年好多了,可以习惯不回复了。我也不喜欢打一两句话就发出去这样聊天,一下子整件事完整说出来我看着比较舒服。一条一条地看真的很麻烦。 那什么交流方式比较适合我呢?电子邮件吧。电子邮件有邮箱地址就能发,不需要加好友。而且收到邮件不回复或者不马上回复心理也比较放松。收到邮件可以加标签或者放入不同文件夹,事后再处理也行。我身边的人都用微信交流,我用电子邮件估计会水土不服。现在已经加了微信的就不管了,下次有人找我要联系方式我就给邮箱。微信就只用来和亲人联系。其实我觉得 Telegram 比微信好多了,但身边人不用也是没办法。社交软件就是这样,用的人多了,即使它是垃圾还得用。很想告诉微信好友我改用电子邮件了,不知道会有什么反应。 现在毕业了,还没处理完档案派送的事情,还留着好多群。毕业后辅导员发信息都不往通知群发了,看信息看得我怒火中烧…… 准确来说,Linux 官方版是 UOS 独占。其他 Linux 发行版一般用 Wine 运行 Windows 版。 ↩︎

2021/7/9
articleCard.readMore

小孩能玩游戏吗

有个亲戚家的男孩让我印象很深刻。男孩现在五年级,放假的时候就宅在家打手机游戏。据我观察,应该是玩大逃杀类射击游戏,俗称吃鸡1。男孩玩的时候常说粗话,有时候是开语音骂的,一般都是骂别人玩得差。有时候也指挥别人,比如「XXX,把枪给我」。玩一个小时能说三四十分钟粗话,一个小时说的粗话比我一年都多,基本上流行的粗话都说了。我当时听到那么多粗话真的感觉很不舒服,真的是该管管啊。难道男孩家长不管吗?并非如此,男孩说粗话的时候家长也会制止,男孩就嬉皮笑脸的,似乎没认识到说粗话对别人的伤害。家长管教收效甚微,慢慢就懒得管了。 我从男孩家长那了解到男孩放假的时候基本都是一直打手机游戏,家长也尝试过没收手机不让玩,但是男孩又哭又闹,家长也是束手无策。我觉得家长已经从管教到放弃了。身为游戏玩家,我也挺理解男孩的处境的,竞技类游戏不是说停就停的。其实竞技类游戏就和体育比赛差不多,如果一个运动员在比赛中途被家长叫停,那这位运动员会输掉比赛,并且可能面临处罚。这位运动员肯定气坏了,打游戏也是这个道理。 我也很理解男孩为什么那么沉迷游戏。上学本来就很无聊,放假也没事做,总得找点事打发时间,游戏刚好是唾手可得的娱乐方式。我小学的时候都是盼望周五放学在家打小霸王。我有个朋友说:「父母不懂教育孩子是因为他们忘记自己是怎么长大的。」如果家长能回忆一下自己的读书经历,想一想背书刷题是不是很无聊,那应该就能理解为什么小孩要打游戏,真的是要放松一下啊。家长既不想了解游戏,也不想让男孩打游戏,就只能用没收手机这种没用的手段。 小孩玩游戏没问题,不过要玩适合的。玩游戏也有讲究,不是随便玩的。首先我推荐用家用游戏机玩游戏,目前主流的厂商是微软、索尼和任天堂,买这三家最新的主机准没错。我推荐游戏机是因为里面的游戏一般都有分级,买游戏的时候看上面标注的分级信息就知道合不合适小孩玩。游戏分级系统就是用于帮助消费者选择适合的内容。美国和日本都有专业的分级机构,有专业机构给游戏分级,家长挑选游戏也更简单。以下是 ESRB(Entertainment Software Rating Board;娱乐软件分级委员会)的分级制度。 标志 分级 描述 E — 所有人 其中内容适合6岁或以上的玩家。被分为此类的游戏通常包含少量的幻想或者适度的暴力,或者有轻度的不良语言。 E10+ — 10岁以上 其中内容适合10岁以上的玩家。被定为此级别的游戏通常会包含具有卡通效果的暴力、或者最少限度的争议主题。 T — 青少年 其中包含适合13岁(英文Teen指13-19岁青年)以上的玩家的内容。此级别游戏会包含暴力、争议主题、粗鲁幽默、少量血腥。 M — 成熟 其中包含适合17岁以上玩家的内容。此类别游戏有强烈的暴力、血腥、性、粗口、宗教的内容。 AO — 仅限成人 其中包含内容只适合18岁以上的成人。此类游戏通常有强烈的暴力倾向、明显的性和裸体场景。 RP — 有待评级 产品已经提交ESRB审定,正在等待分级结果。这个标志主要是在游戏正式发布前的宣传材料中使用。而在可能分级为T级或以上时,会加入一句"May contain content inappropriate for children."(可能含有儿童不宜内容)的免责声明。 我觉得男孩玩的大逃杀类游戏真的不太适合他的年龄。我不知道他具体玩的是哪款游戏,我就查了同类型的 PUBG Mobile。PUBG Mobile 的分级是 Teen,也就是 13 岁才能玩,而五年级的学生一般是 11 岁,这显然不适合男孩玩。其实我也想知道他玩的是啥,但我真的很讨厌别人说粗话,就没过去问,只好靠猜了。 从游戏内容上来说,我也觉得不太合适。大逃杀类游戏经典模式是这样的:把 100 个人丢到岛上相互厮杀,最后存活的队伍或人胜利。100 个人里面赢家就只有 1 个人或队伍,剩下的都是输家。这是很残酷的游戏,要是一直输肯定充满挫败感。我看男孩常常骂人,估计是没赢多少局。我觉得玩游戏就是为了开心,玩单机游戏就挺好的。单机游戏关卡难度一般都是固定的,玩家只要技术进步了,就能过关,这样也会有持续的快乐。而竞技类的游戏是和人对抗的,玩家技术进步的时候可能匹配到的对手也强了,所以总是有输有赢。竞技类游戏真的不适合每一个人,菜鸟体验就差。 以上只是我作为游戏玩家的一些思考,「小孩怎么玩游戏」这个问题肯定不是那么简单。中国一直有污名化游戏的现象,2000 年光明日报称电脑游戏为「电子海洛因」,同年国务院发布游戏机禁令,直到 2014 年上海自贸区细则发布后才解禁游戏机销售。2006 年甚至出现了惨无人道的网瘾电击疗法。需求决定供给,只要还有家长有驯服孩子的需求,那这些粗暴的行为矫正机构仍然会横行霸道。 看到那么多污名化游戏的现象,我真的特别难过,孩子打游戏有什么错呢?很希望有人能出来为游戏正名。后来我真的读到了一本为游戏正名的书,叫做《边游戏,边成长》。这是一本讲述如何带小孩玩游戏的书,作者是心理学者叶壮。作者不仅支持自家小孩打游戏,还列举了打游戏的好处,我读的时候真的特别感动。以前我看论证打游戏合理性的文章说游戏只是一项娱乐活动,没什么特别的。《边游戏,边成长》就高超多了,它说打游戏的好处。 比如经常玩动作游戏的人,眼睛更容易注意到一些细节,这在审题、阅读论文以及看药瓶上的小字时,都十分有用。 除了注意力之外,游戏玩家的多任务处理能力也不错,这可以帮助他们在日常生活中更好地应对那些不得不“三心二意”的场景,以及在学校与职场中更好地同时兼顾多个不同的任务。 好玩的游戏一定是能激活玩家情绪、情感的游戏,而优质的游戏也会通过激发孩子的情绪感受,帮助孩子更好地收获多样化的情绪体验,甚至排解压力。 哈佛大学主要的教学医院贝斯以色列女执事医疗中心发布的一项研究发现,如果腹腔镜外科医生每周能玩超过三个小时的电子游戏,在手术中的错误就会比他们那些不玩游戏的同事少37%。 一个打游戏认真的孩子,起码具备了“认真对抗压力”的能力,他只是有可能不愿意把这种能力用在学习上罢了。但是我们必须要承认,这种能力是一种很重要的优质技能,并且不少游戏对培养这样的能力有着显而易见的好处。 ——《边游戏,边成长》 我前面写那么多,真的希望消除大家对游戏的偏见,希望不要有孩子被改造了。在现实中遇到男孩这样的「网瘾少年」,我心情就很复杂,我很同情他被家长阻止打游戏。我想了解他玩的是什么游戏,但听到粗话就不想靠近。我也想帮帮他,但又觉得很无力。如果要帮他,肯定要改变他家长对游戏的误解,这已经超过我能力范围了,人的观念真的是很难改变啊。我想带他玩既适合他又好玩的游戏,但会不会玩了之后他就缠着找我打游戏,我也没那么多时间陪他玩。会不会玩了之后他让家长也买台游戏机,那我不是加剧了矛盾?这事真的挺复杂的,心里真是五味杂陈。 # 娱乐软件分级委员会 - 维基百科,自由的百科全书 中国大陆游戏机历史 - 维基百科,自由的百科全书 家用游戏机入华 - 维基百科,自由的百科全书 在绝地求生游戏获得第一名后屏幕会显示「大吉大利,晚上吃鸡」,所以绝地求生亦被成为「吃鸡」。 ↩︎

2021/6/25
articleCard.readMore

密码管理器

网上冲浪十余载,帐号越来越多。真的很难记得住每个网站的帐号密码,把帐号密码直接存在笔记软件也不安全。是时候用密码管理器了。我的需求是:跨平台(Linux、Windows、Android、浏览器)、便宜。上网搜寻后发现比较多人推荐 1Password 和 LastPass,它们都是每月3 美元。LastPass 有免费套餐,但只支持一类设备,电脑或者移动设备。所以用 LastPass 还是要付费才行。 最后选中 Bitwarden,它是跨平台开源软件,而且还免费。付费会员也比较便宜,每年 10 美元。现在终于不用记那么多密码了,大脑都轻松了。 注意事项:Bitwarden 的密码一定要记好,忘记了是没法重置1的,只能根据填写的密码提示回忆。实在是想不起来可以通过删除帐号来清空数据,然后再重新注册。 其他密码管理器的密码也无法重置,这算是密码管理器的特点了。 ↩︎

2021/6/24
articleCard.readMore

红米 AC2100 刷入 OpenWrt 固件

相关文章:红米 AC2100 刷 breed 后刷回官方固件 红米 AC2100 刷机的主要步骤:获取 SSH 访问权限、刷入 bootloader(Breed)、刷入固件。 # 红米 AC2100 牙签或卡针 2 条网线1 带网线插口的电脑(没有就买 USB 网口) # AC 2100 WAN 口连接调制解调器或者原路由器 LAN 口,或者通过无线中继的方式联网 AC2100 的 LAN 口连接电脑,全程都要保持网线连接 访问 192.168.31.1,配置网络,保证 AC2100 可以联网 # 下载 2.0.7 固件(备用链接),接下来就利用这个固件的漏洞来刷机 在浏览器访问 192.168.31.1->常用设置->系统状态->手动升级->加载固件,保留数据->开始升级 # 访问 http://192.168.31.1/cgi-bin/luci/;stok=<STOK>/web/home#router,输入密码登陆,登陆后记下网址里面 <STOK> 位置那串字符,例如 c8630022ae04sjf92af0ejd83e0330f1 把刚刚获取的 <STOK> 填入 http://192.168.31.1/cgi-bin/luci/;stok=<STOK>/api/misystem/set_config_iotdev?bssid=Xiaomi&user_id=longdike&ssid=-h%3B%20nvram%20set%20ssh_en%3D1%3B%20nvram%20commit%3B%20sed%20-i%20's%2Fchannel%3D.*%2Fchannel%3D%5C%22debug%5C%22%2Fg'%20%2Fetc%2Finit.d%2Fdropbear%3B%20%2Fetc%2Finit.d%2Fdropbear%20start%3B,然后访问,网页会显示 {"code":0} # 访问 http://192.168.31.1/cgi-bin/luci/;stok=<STOK>/web/home#router,记下 <STOK> 把 <STOK> 填入 http://192.168.31.1/cgi-bin/luci/;stok=<STOK>/api/misystem/set_config_iotdev?bssid=Xiaomi&user_id=longdike&ssid=-h%3B%20echo%20-e%20'admin%5Cnadmin'%20%7C%20passwd%20root%3B,访问,此时密码设置为 admin 如果要设置其他密码就重复前两步,把网址的 admin 改为你想设置的密码,记下密码 # Breed 是由 HackPascal 开发的 bootloader,有了它之后 AC2100 刷成砖也能再刷机。 打开终端程序,例如:Windows PowerShell 依次执行以下代码,一次一行,# 开头的不需要执行 1 2 3 4 5 6 7 8 9 10 # 登陆 root 账户,输入 root 账户密码 ssh root@192.168.1.31 # 下载 Breed curl https://breed.hackpascal.net/breed-mt7621-xiaomi-r3g.bin --output breed-mt7621-xiaomi-r3g.bin # 备用链接 # curl https://cdn.jsdelivr.net/gh/CyrusYip/blog-static/other/breed-mt7621-xiaomi-r3g.bin --output breed-mt7621-xiaomi-r3g.bin # 刷入 Breed mtd write /tmp/breed-mt7621-xiaomi-r3g.bin Bootloader # 重启 reboot 等待重启,只有蓝灯常亮代表重启完毕 # 下载临时固件 拔下 AC2100 的电源,用牙签按住 Reset 键,插电,蓝色闪烁时松开 访问 192.168.1.1,增加环境变量,字段为 xiaomi.r3g.bootfw,值为 2,保存。不做这一步 AC2100 就无法启动了。 备份固件(可跳过) 固件更新->固件->选择文件->选刚刚下载的临时固件->勾选自动重启->上传->更新 # 下载 OpenWrt 固件 恩山论坛有很多 OpenWrt 固件选择一款合适自己的就行。我用的是这个,下载地址在这里,下载文件名含有 sysupgrade 的文件。自己编译也行。 重启完后访问 192.168.1.1,如果被占用了就拔掉 WAN 口的网线 System -> Backup / Flash Firmware -> Flash image -> 取消勾选 Keep settings and retain the current configuration -> continue 访问 10.0.0.1,配置 AC2100 # 第一次给路由器刷机,一搞就是几个小时,天都亮了,太艰难了。一开始我是连着 WIFI 弄的,结果一直不行,后来才发现要接网线。网上有各种方法,有些方法要安装软件,看着就头疼啊。我觉得现在我这个方法还算简单,只需要终端和浏览器,这两个软件每台电脑都有。 看了那么多教程,我觉得 OpenWrt 网站的资料写的最清晰易懂。可以先从这里入手,不行再看其他教程。不过我没测试过这里面的所有内容,我也不知道是不是都有效。另外,这个帖子提到了 AC2100 有内存坏块可能导致无法刷机。 # [OpenWrt Wiki] Xiaomi Redmi Router AC2100 小米 红米【AC2100】一键刷BREED【30秒刷完】小白脑残专用 无需工具TELNET + 检查坏块 - 小米无线路由器以及小米无线相关的设备 - 恩山无线论坛 [0825:AC2100新固件有效AX6无效]AX3600/AX1800/AX5/AC2100官方固件开启SSH方法[原创] - 小米无线路由器以及小米无线相关的设备 - 恩山无线论坛 【2020-10-09】AR/QCA/MTK Breed,功能强大的多线程 Bootloader - OPENWRT专版 - 恩山无线论坛 1 条网线从 LAN 口连接到电脑,另 1 条从 WAN 口连接到调制解调器(猫)。如果本来就有路由器的话,可以只用 1 条网线从 LAN 口连接到电脑,然后用无线中继的方式连接原有的 WI-FI。 ↩︎

2021/6/19
articleCard.readMore

鼓励

如果我的文章帮助到你,你可以通过以下方式鼓励我。 # 留言感谢我 # 分享文章给需要的人 分享博客 # 请我喝瓶东方树叶😊。 Patreon(信用卡、Paypal、Apple Pay) # DigitalOcean:知名服务器提供商,点击此链接注册,你会获得有效期为 60 天的 100 美元余额。你用自己的钱消费一定数额后,我会收到余额奖励。 Vultr:知名服务器提供商,点击此链接注册,你会获得有效期为 30 天的 100 美元余额。你用自己的钱消费一定数额后,我会收到余额奖励。

2021/6/10
articleCard.readMore

牙的回忆

第一次蛀牙 # 不记得小学几年级开始有的蛀牙,去看牙医的时候大概五六年级。下排的牙齿左右两边各有一个蛀牙,超过一半都烂了。医生还发现我右上方有个突出的牙齿,说我初中的时候可以去箍牙(矫正牙齿/口腔正畸),这样牙齿会比较好看。 # 小学(或是初中)住宿的时候,在一个夜深人静的晚上,舍友听见了有人在厕所嗑瓜子。嗑瓜子的声音间隔特别规律,应该是两三秒发出一次声音。舍友走到厕所却发现没人,但是嗑瓜子的声音还在持续…… 谜底写在文章后面了,你可以先猜猜故事的真相。 # 初中的时候自学编程,源代码的有不少不懂的英文单词,于是打算先学英语。我用的书是《李阳国际音标与美国音标入门》。自学音标的时候,/ð/ 和 /θ/ 这两个音标总是学不会,怀疑是自己的牙齿位置不对导致无法发这两个音。于是就去矫正牙齿了。一般人矫正牙齿都是为了好看,我是为了学习,真的是朵奇葩。 矫正牙齿之后我还没放弃学音标。当时音标吧有位老哥发帖说免费教音标,我就加了他的 QQ,老哥的昵称是 Reborn。Reborn 哥推荐我学赖世雄的《美语音标》1,赖世雄水平真是高,听了他的讲解我就学会了。 但是矫正的牙套都戴好了,没法回头了,直接拆掉的话牙齿就会处于未矫正完成的状态,比矫正前还糟糕。没办法,矫都矫了,只能继续。戴牙套的第一个星期特别煎熬,咬有点硬的食物整排牙齿都痛,唯一吃了不痛的食物就是粥了。吃东西也危险,有次吃无穷鸡腿的时候把牙套的线扯出来了,然后就要去医院请医生弄好。从那以后,无穷鸡腿就进了零食黑名单。 矫正好后拆掉牙套,我妈发现我的牙有点歪,然后去质问医生。医生说少拔了一颗牙,问退钱还是重新弄。我去市人民医院问了牙医,医生也是说要拔一颗才行。我懒得换医院了,又回到原来的医院弄了。初三开始弄,好像大一才弄好,还得戴半年保持器。这么说也过了好几年呢,回想起来感觉真不容易,要是一开始知道那么麻烦估计就不想做了。 # 大四上学期一门课的期末论文上交时间本来是下个学期开学前,但是老师突然把期末作业的上交时间提前到五天内。当时我就一边在心里痛骂老师,一边拼凑论文,也没时间做饭了。女朋友帮我点了外卖,无骨炸鸡和韩国年糕。吃着吃着的时候,我嘴里吐出了一块白色的骨头。嗯……无骨炸鸡怎么有骨头呢,而且还是白色的,鸡骨头不是这个颜色啊。嗯……我舌头有种奇怪的感觉,好像右下方补过的牙缺了一块。啊啊啊啊啊!白色骨头是我的牙,居然被年糕粘掉了,补牙材料真的不行啊。突然要赶论文就很火大了,还遇上这样的糟心事,于是又痛骂了老师。这个老师平时对学生太差了,骂一百遍都嫌少。 # 去医院补被年糕粘掉的牙,叫医生顺便检查其他牙齿有没有问题。医生发现我还有五六个蛀牙。天哪,我一直以为我只有两个蛀牙,居然又多了几个,真是要命。第一次只补了一颗。第二次去的时候补了几颗,电钻碰到牙齿里的肉,痛到流泪了。在补牙过程中,我无数次悔恨自己没有好好爱护牙齿。补一颗牙四五百,学生医保还不报销治疗费,都是自费,心痛死了。补完牙后医生建议我用巴氏刷牙法和电动牙刷。上丁香医生看巴氏刷牙法才知道我的刷牙方法一直是错的。后来买了电动牙刷,刷牙真的比手动的方便,还更干净了。顿时感觉白刷了 20 年的牙。电动牙刷真是伟大的发明。 # 平时一定要正确刷牙,有蛀牙一定要补啊。到不能补牙的时候很悲惨的,只能镶牙或者种牙了。镶牙会磨损旁边两颗牙齿,种牙就把假牙钉到骨头里。想想都觉得可怕,而且还贵,种牙是几千上万一颗。幸亏我补了牙,没走到这个地步。看来还是要定期检查牙齿才行啊,预防是最好的治疗。 补牙 镶牙 种牙 # 鬼故事发生的时候我睡着了,我第二天才听舍友说这件事。起床的时候我发现一个补过的牙缺了一小块,而且缺的那小块不知道哪去了。故事应该是这样的:我就是「嗑瓜子的鬼」,晚上磨牙还把牙磨掉了一小块,那小块应该吃进肚子了吧。当时觉得磨掉牙齿这件事太丢脸了,就没告诉舍友,也不知道他们后来晚上会不会害怕。 我按照《把你的英语用起来!》自学英语,这本书也推荐了《美语音标》。我也不太清楚我一开始是从哪里知道这本音标教程。我不记得具体和 Reborn 聊过什么,总之就是对他有很深的感激之情,那他应该帮到我了。所以是先从他那里知道的。啊,人的记忆也不是那么好使,真的是不写下来就慢慢遗忘啊。 ↩︎

2021/6/9
articleCard.readMore

Git 笔记

术语 # 工作区(Working Directory):从某个版本独立提取出来的内容,也包括未被 Git 管理的文件。简单来说就是 .git 文件夹以外的内容。 暂存区(Staging Area):记录了待提交信息的一个文件。 仓库/版本库(Repository):Git 用来保存项目的元数据和对象数据库的地方,也就是 .git 文件夹。 # 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 # 名字和邮箱必须设置,其他按需要配置就好 git config --global user.name "your-name" git config --global user.email "your-email" # 设置远程分支后才能用 `git push` git config --global push.default simple # 显示中文路径 git config --global core.quotepath false # 设置编辑器 git config --global core.editor "nano" # 设置换行符为 LF git config --global core.autocrlf input # 设置好看的 git log git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit" git config --global alias.lgs "log --pretty=oneline --graph --abbrev-commit" # .gitignore 用于忽略不需要的文件,例如: 1 2 3 4 node_modules .DS_Store .idea .vscode # 配置命令别名后操作更简单,Oh My Zsh 的 git 插件就自动配置了别名。如果不用 zsh,手动添加别名到 ~/.bashrc 也行。 1 2 3 4 5 6 alias ga='git add' alias gc='git commit -v' alias gl='git pull' alias gp='git push' alias gco='git checkout' alias gst='git status' # 1 2 3 4 5 6 7 8 9 10 11 12 13 14 # 生成 SSH 密钥(ed25519 比 RSA 安全) ssh-keygen -t ed25519 -C "注释" # 查看密钥 cat ~/.ssh/id_ed25519.pub # 复制代码 xclip -selection clipboard < ~/.ssh/id_ed25519.pub # 添加密钥到 GitHub xdg-open https://github.com/settings/ssh/new # 接收 GitHub 公钥 ssh -T git@github.com GitHub 文档 # 1 2 3 4 5 # 初始化当前目录 git init # 初始化文件夹 git init directory-name # 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 # 查看分支 git branch # 创建分支 git branch branch-name # 切换分支 git switch branch-name git checkout branch-name # 创建并切换分支 git switch -c branch-name # -c --create git checkout -b branch-name # -b(branch) # 删除分支 git branch -d branch-name # 合并分支 git checkout main # 切换到接受代码的分支 git merge patch # 把 patch 分支的代码合并到 main # 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 # 克隆仓库 git clone repo-link git clone repo-link local-repo-name # 克隆并重命名 git clone repo-link . # 克隆到当前文件夹(不推荐) gh repo clone username/repo-name # 添加远程仓库 git remote add remote-name repo-link # 查看远程仓库 git remote -v # 删除远程仓库 git remote remove remote-name # 推送代码 git push remote-name local-branch:remote-branch git push -u remote-name branch-name # 设置上游 git push remote-name branch-name git push # 拉取代码 git pull remote-name branch-name git pull # 1 2 3 4 5 # 详细内容 git status # 精简内容 git status -sb # 1 2 3 4 5 6 7 8 9 10 11 # 添加文件 git add file-name git add file-1 file-2 # 添加目录 git add directory-name # 添加所有文件 git add . git add * git add --all # 1 2 3 4 5 # 恢复所有 git reset -- . # 恢复某个文件或目录 git reset -- file-name # 1 2 3 4 5 6 7 8 # 隐藏暂存区 git stash # 查看隐藏内容 git stash list # 恢复内容 git stash pop # 1 git clean -di # 以下方法删除的内容仍然可以被恢复。如果要完全删除,请参考完全删除 Git 仓库的文件。 1 2 3 4 5 6 # 方法 1(推荐) git rm file-name # 方法 2 rm file-name git add file-name # 1 2 git commit -v # 在提交说明底部显示 diff git commit -m "提交说明" # 不推荐 # 1 2 3 4 5 6 7 # 查看历史 git log git log --pretty=oneline --graph --abbrev-commit git log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit # 查看所有历史(git reset 之前的都有) git reflog # reflog 只在本地,不会上传到远程仓库 # 1 2 3 # --hard 会删除暂存区的文件 git reset --hard commit-id git reset --hard HEAD # git status 查看冲突文件 打开冲突文件 搜索 ======= 删除冲突文件里的 <<<<<<< HEAD、=======、>>>>>>> branch-name 修改文件,留下需要的代码 git add conflicted-file 解决完所有冲突再运行 git commit # 1 2 3 4 5 6 7 8 9 # 合并提交 git rebase -i HEAD~3 git rebase -i commit-id # 取消 rebase git rebase --abort # 继续 rebase git rebase --continue

2021/6/7
articleCard.readMore

困难的恋爱

困难的恋爱 # 毕业以后恋爱就变困难了。之前学校天天见,现在就开始异地恋了,非常不习惯。女朋友目前做教师,我打算做程序员,目前在家里学前端开发。我很粘女朋友,异地恋太煎熬了,于是就在思考怎么结束异地恋。 做程序员得去大城市找工作,女朋友目前在小城市工作。我上 BOSS 直聘搜了下,小城市压根就没有前端开发的工作。看这样子还是得异地恋。现在只有两个方案:女朋友迁就我去大城市工作、我迁就女朋友去小城市工作。 正如袁凡所说: 但也许你进入社会后会面对一个残酷的现实,那就是找工作这件事上高学历好学校是一块好的敲门砖。 女朋友迁就我不太可行,去大城市做教师也得研究生起步了。本科学历真的是不够用,女朋友也没有读研的想法。走这条路实在是牺牲太大了。 我迁就女朋友也不太行啊,小城市真的没前端开发的工作。最后我想到一个折中方案:我去大城市工作几年,积累技术和经验,然后找份远程工作,搬过去女朋友那边。问了一个程序员朋友在国内远程工作可不可行。朋友说:「可以,但是只懂前端不够用,要成为成为全栈工程师才行。自己能独立完成任务才行,不然可能需要即时的交流,这就得在公司上班了。」嗯,这个方案可以。也有想过自由职业,但觉得一开始就这样不太容易,真的不知道要干什么,还是先去打工赚钱养活自己吧。现在就继续努力学习吧,加油! # 上大学之前读书都有别人设定好的目标,比如中考和高考。只要按部就班的学习和考试,慢慢就过去了,也不会纠结人生意义这种问题。上大学之后就更自由了,没有什么固定的目标,考试六十分万岁,不用像高考那样争个你死我活。一下子失去目标,整个人都迷茫了,感觉生活没什么意义。和心理咨询师谈了很多次迷茫的问题,最后也没找到我的目标。 现在和女朋友分隔两地,我真的特别珍惜这段恋情,所以我就有了个人生目标:结束异地恋。现在学编程也有累、无聊、不想学的时候,但是想着要结束异地恋,就会休息过后再继续学习。以前总觉得人生没什么意义,现在好像突然就有意义了,能和女朋友在一起就够了。感谢女朋友一直的陪伴、照顾和支持。遇到她之前,我的生活黯淡无光。相恋后,我的生活已是五彩缤纷,充满希望。

2021/6/4
articleCard.readMore

不推荐使用 cn 域名

2025-03-31 更新:cn 域名已经支持隐私保护了(例子)。 去年想学习搭建网站,当时啥也不懂,以为建站一定要有服务器、域名和备案。于是在腾讯云租了一年服务器,付费的时候看到 cn 域名才 17 块,就顺便买了一个。备案过程十分曲折,要填很多个人信息。备案后那段时间没空学建站,然后因为一周1内没有解析网站,备案就自动注销了。真的是气死,辛辛苦苦备案完,还给我注销了。最近又看了些 cn 域名的资料,发现有挺多坑人的地方。 cn 域名没有隐私保护(whois protection)。国内域名注册商说的隐私保护根本是自欺欺人,在它们隐私保护就是在自己的查询服务隐藏注册人信息。但在别的地方是能查到的,在中国互联网络信息中心2可以查到每个 cn 域名注册人的姓名和邮箱。 注册 cn 域名必须使用真实身份信息。要是你想用假信息注册来保护隐私,那就太天真了。审核的时候不会通过的。真的不想用自己的信息注册的话,要么以公司名义注册,但公司的法定代表人还是能查到的。要么叫别人注册域名之后给你用,可谁愿意冒这种风险呢。 cn 域名无法删除。如果你觉得 cn 域名暴露了你的隐私,那对不起,这是不能注销的3。你只能修改邮箱地址,然后等到它过期。或者转让给别人,不过感觉把别人推到火坑里不太好啊。 cn 域名有被停用的风险。2008 年,有人以跳水奥运冠军吴敏霞拼音注册了 wuminxia.cn,结果被中国互联网络信息中心(CNNIC)回收了域名,并转交给国家体育总局。此域名在 2021 年 2 月 28 日被优视科技注册,呵呵。2009 年,牛博网被域名注册商万网停止解析。 其他 CNNIC 的争议就不讲了,感兴趣就去看维基百科吧。 其实我不记得具体时间是不是一周,大概是这样吧。 ↩︎ Godaddy 、Whois.com 和命令行程序 whois 也可以查询。 ↩︎ 您好,域名属于即时产品。域名注册成功后不能删除,也是无法进行注销的。若您不需要此域名,您可以等到域名到期不续费即可。——腾讯云 ↩︎

2021/5/25
articleCard.readMore

把域名转移到便宜的域名注册商

2023-05-02 总结:最便宜的域名注册商是 Cloudflare,但它有些缺点:不能改域名服务器、WHOIS 信息会显示注册人地址的国家与省份/州,不过其余信息会被隐藏。不喜欢 Cloudflare 的话可以选择 Porkbun。注册或转移域名 60 天后才能转移域名,这是 ICANN1(互联网名称与数字地址分配机构)的规定。请选择 ICANN 认证注册商(ICANN Accredited Registrars)。要是去买三手四手的域名,出了问题 ICANN 都保不了你。 最近发现了两个域名价格对比网站:TLD List、domcomp,在上面搜了一下我的域名 cyrusyip.org,发现续费最便宜的是 Sav(10.15 美元) 和 Porkbun(10.72)。我用的 Namecheap 续费要 15.16,相比之下 namecheap 真的不太 cheap。虽然网上可以搜到 20% 优惠券,用了之后(12.12)还是比较贵。而且每次都要找优惠券,有点麻烦。由于Sav 的评价不太好,我就决定转移到 Porkbun。转移费是 10.72,转移后域名使用期限会加 1 年。所以其实转移是免费的,转移费拿去续费了。 转移步骤: 在 Namecheap 找到转让选项(Transfer) 解锁(unlock)网站 获取认证码(AUTH CODE) 注册 Porkbun 到 Porkbun 点击 TRANSFER 填写域名和验证码 付费(可用支付宝,好评!) 收到 Namecheap 的通知邮件,打开里面的链接 点击确认(Approve) 点击确定之后过一两分钟就好了,也保留了原来的 DNS 记录,所以网站在转移中不会被关闭。以后每年都可以省 28 块人民币了,非常好!要是有优惠券就更省钱啦,不过好像没有续费优惠券。都那么便宜了,我还想用优惠券,实在是太贪心了。Porkbun 的界面很简洁,还用了粉色,我太喜欢了! 又及,我发现最便宜的域名注册商可能是 Cloudflare。它的收费等于成本价。 Cloudflare Registrar will only ever charge you what we pay to the registry for your domain. Cloudflare 的续费价格是 10.11,比 Porkbun 便宜了 0.61。 2021-08-28 更新:今天把域名迁移到 Cloudflare 了。步骤如下: 在 Cloudflare 主页点击 Add site,根据提示添加域名 在 Cloudflare 主页点击 Registrar -> Transfer,按提示操作 操作成功后扣了 10.11 美元,转到 Cloudflare 后就不能更改域名服务器了,除非把账户升级为 Business(200 美元/月)。域名转到 Cloudflare 之后域名 WHOIS 信息会显示国家和省份/州。原来低价域名是推广 Cloudflare 的手段。本站目前用 Vercel 部署,Vercel 和 Cloudflare 都提供 CDN,这岂不是套了两层 CDN。果然 Vercel 文档说 Cloudflare 会稍微降低网站性能: We don’t recommend that you enable the Cloudflare proxy unless you have specific constraints for your project since it will introduce a minor performance penalty to your website due to the additional hop. 按照说明把 Proxy status 改为了 DNS only,然后把 Quick Start Guide 那些功能都关掉。因为博客的 RSS 用太多 Vercel 流量,我又用 Cloudflare 缓存了。 ICANN /ˈaɪkæn/,全称 Internet Corporation for Assigned Names and Numbers(互联网名称与数字地址分配机构),是负责分配域名和 IP 地址的非营利组织。 ↩︎

2021/5/19
articleCard.readMore

为什么要接纳自己

接受自己好的一面 # 前段时间通过了论文答辩,过程十分顺利,回答得也不错。结束之后答辩老师也没有说论文有问题。那天我还遇到了几位同学,她们的论文都被指出有问题。再过几天学院公布了第二次答辩名单,我们专业有 20% 的人要去二辩。 和其他同学对比的话,我应该算挺好的,感觉很开心。好像这是第一次为超过别人而感到自豪。本来想发朋友圈表达喜悦,想想还是算了,微信有那么多同学,怕被他们说我炫耀。 以前我渴望认同,而发朋友圈就是一个轻松获得认同的方式。有人点赞我会很开心,没有就很失落,甚至觉得尴尬。我发现发照片或包含强烈情绪的动态会有更多人点赞,但是那些长长的生活感悟就没什么点赞。为了点赞我甚至还压抑表达内心所想,越来越少发感悟,就只发那些觉得会有人点赞的内容。 现在我不想被朋友圈点赞裹挟,也不想否认自豪的感觉,所以还是在内心为自己高兴就好。人无论处于什么境地,都有思想的自由。 我前段时间开始在 Stack Overflow 答题,我回答的第一道题有 3 个赞,感觉很开心。我甚至会为了点赞去回答问题。 前面我说了不想被朋友圈点赞裹挟,现在又说很享受 Stack Overflow 的点赞,这是自相矛盾吗?实则不然。朋友圈点赞和 Stack Overflow 点赞的意义不一样。朋友圈的点赞代表喜欢,而 Stack Overflow 的点赞(upvote)代表答案有用(helpful)。朋友圈有很多赞,代表大家很喜欢我发的动态。Stack Overflow 有很多赞,代表我的答案帮到很多人,是对我知识和经验的认可。 Stack Overflow 的赞会促使我去学习和输出知识,而朋友圈的点赞会促使我去讨好别人。学习对我来说是有益的,讨好别人是有害的,所以我不愿意被朋友圈裹挟,但很愿意被 Stack Overflow「裹挟」。可见点赞并不总是邪恶的,只要点赞对我来说有益,我就愿意受它的影响。 # 在 Stack Overflow 答了几道题之后就没什么可以回答的了。然后我就去 Stack Exchange 的英语学习版块(English Language Learners)看了看。我想:英语可是我的专业啊,赶紧来答几道题。看了一轮,发现这些题目还是有些难度,最后还是找到了一道比较简单的:「sit 和 my lap 之间用 on 还是 in」。我写了个答案分析 on 和 in 的差别。万万没想到有人点了个反对,还有人说用逻辑分析习语(idiom)是不对的。 看到反对和评论的第一反应是十分羞耻,像是当着全班的面答错问题。不过这个的范围比一个班级大多了,全世界都能看到我的回答。真担心我的读者发现我身为一个英语专业生还回答得那么糟糕,简直想把这个答案删了。其实也不用那么担心,毕竟我的没什么名气,只有三个常驻读者。 我还是忍着羞耻感仔细地看了那条评论,确实说得有道理。英语语法有规律,但也有例外,尤其是习语,这些例外只能是死记硬背。还有个答案的角度是对比 sit in lap 和 sit on lap 的使用频率,最后发现 on 用得更多。我觉得这个角度就比我那个好多了。 最后还是没删答案,写博客的人哪能那么小气呢!把答案留下来是因为 我觉得我的答案还是有些道理。 删了答案那条颇有道理的评论会消失。 提醒自己下次好好写答案。 强迫自己接受不如他人的感觉。求知是从承认自己无知开始的,哪个大师不曾是菜鸟呢?习惯这种感觉有很大好处,别人的反对意见可能是看待问题的另一个角度。 # 之前看心理学科普书说要接纳自己,曾经这对我来说是件很费解的事,为什么要接纳自己呢?现在我能接受自己好的一面,也能接受自己不好的一面,似乎想明白了为什么要接纳自己。接纳自己就是为了更好地做自己,而不是成为他人期待的样子,也不是成为他人。成为他人既痛苦,也不可能,还是做自己比较舒服。

2021/5/14
articleCard.readMore

念头不等于现实

颓废 # 大学最后一个学期没有课,唯一的任务就是写毕业论文和答辩1。有好几个月的时间做,时间很充分,但是我的焦虑感很严重。有时候会被焦虑压垮,要通过吃油炸食品和熬夜看动画来释放。本来前段时间是在坚持锻炼的,但是压力大了就停止了。最痛苦的是不能从论文中脱离。 写到不想写的时候,身体会很自然地停下来,切换到浏览器看看视频和文章。放松一下也没什么不好的,可我就是强迫自己继续写。看视频的时候就不能好好投入,责备自己没有好好写论文。所以我会看一段时间就回去写一点,写了又不想继续,然后去看视频。看了视频就自责,然后回去写一点。写论文又焦虑,于是去看视频,看了视频又自责,自责了就通过看视频来逃避这种感受。就这样不断循环。所以这几个月常常熬夜。想当年,高考前我都不会失眠,睡得可香了。在大学我也是摸鱼能手,居然就栽在论文上了。 # 这个状态挺糟糕的,既没有好好写论文,也没有好好放松。除了浪费时间,内心也十分痛苦。一是对论文进度的焦虑,二是对浪费时间的自责。 对论文的焦虑是对未知的焦虑。第一次写毕业论文,很多东西都不了解。不知道要多久才能写完,也不知道写得合不合格。当我不了解一件事情的时候,我往往会想得比较糟糕。我会把论文当成很难的事情。对答辩的焦虑亦是如此。 # 其实写论文和答辩的难度远比我想象的低,我的论文上交之后通过了。答辩也顺利通过,答辩老师连修改意见都没有。我们专业有 20% 的同学没通过第一次答辩,看来我做得还不错。 # 当我脑海浮现论文和答辩很难很可怕的念头时,我一下就相信了。于是就开始焦虑,陷入颓废的状态。实际上,每天写花三四个小时的话,一个月就能搞定了,但是我焦虑了好几个月。念头可能是事实,也可能不是。可人常常把自己的念头当作现实,从而陷入不必要的焦虑中。啊,人类是多么不理智。 有两个分辨念头和现实的方法。一是觉察脑中浮现的念头,不要第一时间去相信,可以把它放到一边慢慢审视。觉察能力可以通过修禅/冥想来提升。二是直接去做那些感觉可怕的事情,通过实际状况来修正自己的念头。 答辩就是和几位老师介绍一下自己的论文,然后再回答老师的问题。 ↩︎

2021/5/7
articleCard.readMore

缅怀我的长发

缘起 # 高三那年我诊断出强迫症和焦虑症,症状是一学习就咳嗽1得很厉害。于是没去上学,平时就在学校附近的出租屋自己复习。有天刷知乎看到讲男生留头发的帖子,我看照片还挺帅气啊。干脆我也试试看吧,反正也不用去上课了,不用在意别人的目光。我留长发有三个原因:感觉好看、懒得打理头发、懒得去理发店。上网买了个帽子,就这样开始留头发了。 留头发有三个阶段:能打理、不能打理、成功。 能打理 头发还没特别长的时候我就留侧分,再长一些就留背头了。 不能打理 头发长到遮眼的时候没办法弄发型了,这时候就直接戴帽子盖住这乱糟糟的头发。平时在家就戴发箍,洗了头之后也戴。度过这个阶段就成功啦。 # 打理头发是留头发过程中最简单的事情了,可怕的是被歧视。例如: 同学看我留头发之后以为我无心向学,劝我好好学习。嗯……头发长短和学习没关系好吧。 我爸看我开始留长发,甚是生气。一气之下把老祖宗说的话都搬出来了,和我说:「身体发肤,受之父母。」这是我唯一一次听我爸讲文言文。他还说了那句粤语名言:「生旧叉烧好过生你。」(生块叉烧都比生你好) 回家就比较可怕,会被很多亲戚评判。甚至村里的不是亲戚的人说长头发不像样。 其实我遇到这些歧视都超级伤心,真没想到周围有人对男生留长发有那么大偏见。我觉得随便批评别人很不礼貌,只要别人没损害他人利益,那就没什么好批评的。但世上就是有人看到不符合自己观念的事情就批判一番,真是没办法。旁人的评价感觉还行吧,最寒心的就是父母也歧视我。唉,毕竟做父母不用考试。我并不期待他们能支持,但还是希望别歧视吧。 # 上大学前听闻军训要剪寸头,就去理发店把鬓发剪了,扎了发髻。本来我打算留全部头发,但是就快要剪寸头了,就去把鬓发剪了,这样把头发扎起来看着还不错。 军训开始前去理发店剪寸头,心里居然很平静。可能被歧视得多了,也不差被迫剪掉了。现在想起来还有点遗憾,不是遗憾长发没了,是遗憾没把长发捐献给癌症患者。 军训完之后感觉自己短碎发看着也不错,还不需要用发蜡打理头发,然后就一直留这个发型。以前没试过那么短的发型,没想到这个发型挺适合自己的,这算是因祸得福吧。 偶尔想再留长发,但是女友强烈反对,她觉得我的长发很难看。真是一物降一物,没想到最后栽在女友手里了。现在,我只能看着身份证上的照片,缅怀我的长发。大家有办法说服我女友吗?救救想留长发的我吧。 # 我留长发还是有些影响力。有个高中同学2觉得这样很酷,上大学他也留了长发。村里有个小孩不想剪头发,就和他爸爸说你看某某家的哥哥,人家留长头发就不用剪。 谈恋爱后咳嗽就好了。 ↩︎ 这位同学有时候打扮风格异于常人。有同学说他很捞(「捞」在粤语是俗气的意思),他总会说:「捞到尽头自然潮。」 ↩︎

2021/5/6
articleCard.readMore

关于心理咨询的疑问

最近感觉心理咨询的谈话内容挺值得记录的,就写下来了。 # 我在前三四个星期的一次咨询聊到在大学被剥削的感觉,结束时咨询师觉得这个话题挺重要的,便邀请我下次再谈。然后最近这两三次的咨询都在聊在大学被剥削的感觉。其实我不太想聊被剥削的事情,感觉都聊得差不多了,没什么内容可谈了。虽然我不想谈了,但感觉自己最好还是遵从专业人士的意见吧,继续深入谈同一个话题或许更好。 上周六要考英语专业八级,所以取消了周五的咨询。今天距离上次咨询已经两个星期了,我都忘记上次聊了什么。实在是没法继续聊上次的话题,就和咨询师说忘记上次聊了什么。我在第一次聊被剥削这个话题时,咨询快结束时还说了很多话。咨询师当时就觉得我意犹未尽,那么这对我来说肯定很重要。于是他在结束时就说这很重要,下次再谈。 其实也不是这个事有多重要,只是我不想咨询的时间那么快结束,就在结束前几分钟猛说话。咨询师以为我猛说话是代表这个话题很重要,我又觉得咨询师的意见比较专业,要相信他。于是我们就谈了两三次这个话题,仿佛在一起演戏,把不重要的当成重要。 咨询结束前猛说话是不能接受咨询结束的表现。这有点像我不想睡觉的感觉。有时候我睡觉时感觉自己当天虚度光阴,很想学习一下,补救这虚度的一天。这就是不能结束一天要结束的事实。到了晚上,这一天就是结束了,已经不能补救了。想做的事明天再做便是。如果熬夜补救虚度的光阴,然后导致作息紊乱,这岂不是得不偿失。 咨询亦是如此,反正每周都做一次,不用急于一时,还是慢慢适应结束的时刻吧。现在就顺着自己心情,聊聊感兴趣的话题吧。专业人士也会误解,还是相信自己吧。 # # 对我来说,咨询的作用是排解负面情绪和获得心理成长。我现在做心理咨询没有什么特定目标。现在心理咨询起作用的方式和正念冥想很像,做的时候不追求什么,过了一段时间自己就了些变化。 心理动力学流派1则认为咨询师是要帮助来访者发现潜意识。好像发现潜意识之后人就会变好,感觉很玄乎,这个道理我也不太理解。 # 从咨询师的角度来说,短程咨询2有目标,例如:让来访者情绪平稳。长程咨询可以没有具体的目标。我一开始做咨询也有目标,就是减轻咳嗽3这个强迫症状。慢慢缓解后就没什么目标了。现在还在继续咨询的原因主要是排解负面情绪,之前试过停止咨询,感觉太难受了,就恢复了。 # 咨询会结束。 # 来访者心理慢慢成熟后,咨询师不能帮到来访者了,这时就该结束了。咨询师和来访者都在成长的话,那咨询应该会维持比较久。也有一些比较遗憾的结束方式,比如:咨询师从单位辞职了、来访者无法负担咨询涨价。 我的咨询师就是心理动力学流派的。 ↩︎ 心理动力学流派的短程是 24 周,认知行为流派是 12 周。我是听咨询师讲的,希望没记错。 ↩︎ 咳嗽最严重的时候就是一学习就咳嗽,看书做题都不行。这是我得过最奇怪的病了。这世上居然有让人不能学习的病,不知道有没有人羡慕。这个症状很奇怪,它的治愈方法也很奇怪。我谈恋爱之后咳嗽就好了,心理医生都没法治愈的症状,居然被女朋友治愈了。没想到恋爱还有这等功效,女朋友真的是我的救命恩人啊。 ↩︎

2021/4/30
articleCard.readMore

行李清单

收拾行李对我来说一直是个大难题。每次出门都要收拾很久,还常常丢三落四。现在终于想到了个好办法——行李清单。出门前先写一份行李清单,然后把清单上的东西都拿出来,再逐一清点,有的东西就打个勾。就像这样: 衣服 电脑 书 即使用了清单,我还是会漏掉一些东西或者该做的事,收拾行李实在是太难了……不过我又想到了一个办法——想象要做的事情。把从出发地到目的地之间的事情都想象一遍。 出门前 倒掉水壶的水 关窗 喷杀虫剂 丢垃圾 关灯 路途 步行 雨伞 坐地铁 公交卡 口罩 坐客车 零食 身份证 车票 到达后 起床 眼镜 洗漱 牙刷 毛巾 学习/娱乐 书 电脑 洗澡 衣服 睡觉 其实可以做一份总清单,把所以可能带的东西和要做的事都写进去。每次出门前就复制一份总清单,然后根据情况做增删,增加的内容就再补充到总清单。这样就不用想那么多了。清单挺适合保存到 GitHub Issues 的,存在那里比较方便,手机电脑都能用。

2021/4/27
articleCard.readMore

论文格式是人类退步的滑梯

四个月前吐槽了毕业论文参考文献有两种样式,现在写完论文了,感觉还得再吐槽一番。写论文倒没有多难很难,但更难的是论文格式。论文格式要求真的是太害人了,不吐不快。学院给了一份 5400 字的格式规范。规定特别详细,规定了字体、行距、页边距、页眉页码、参考文献格式……为什么都写了那么长的规范,还不给份模板?难不成要学生从空白文档开始调格式吗?经过我的一番调查,其实是有模板的,但今年没有。那行吧,就拿上一届学生的论文作模板咯。但这论文格式又年年都变,拿上一届学生的来用也得调整。制定格式规范的人啊,你们这帮人到底给学生和导师挖了多少坑。难不成你们是打印店的卧底?这格式规范文件后缀名居然是 .doc,肯定是个祖传文件。 真是出师不利,为了避免被格式折磨到不想再写,我还是先不弄格式了。初稿是用 Typora 写的,在干净的界面上写论文真是如沐春风。写完之后就要把内容迁移到 Word 文档了。多亏女友调好了她论文的格式,我就直接拿她的作模板了。要是没女友相助,我估计直接去第二次答辩了,真是万分感谢。把内容一点一点地粘贴到 Word 文档里面。光是这件事就花了我两三个小时,一边粘贴一边爆粗。 除了要应付繁杂的格式要求,还要担心踩到好心人挖的坑里。有同学在专业群问查重的问题,辅导员就建议直接把文本粘贴到维普网页上,或者上传 PDF。但论文是用 Word 写的,直接复制内容或者上传 PDF 可能会导致维普检测把不该查重的部分也查了。学校就只提供两次查重机会,学校只认这两次的结果。要是上传了错误的文档就浪费了一次宝贵的机会。幸亏维普对粘贴到网页的内容有字数限制,不然同学要中招了。还有同学发了模板,我的火眼金睛看到一句重要的话——「模板不能涵盖所有情况,请参考『附录一 格式规范』。可今年的格式规范是「附录二」,所以这个模板不是今年的。根据上面写的班级,应该是去年的模板。有的同学就更厉害了,发了前年的模板。要不是我头脑清醒,早就被害惨了。 那些纠结细节的同学也很可怕,他们会在群里问没规定的格式怎么弄。比如标题下面要不要加空行,页眉的校徽的位置和大小怎么设置。我觉得格式问题真的没那么复杂,首先遵守学院的格式要求,没规定的格式就参照上一届学生的论文。可靠的信息来源就两个:格式规范、学院老师的答复。辅导员和同学的答复都不见得可靠。这些同学在群里问一问还没什么,就怕他们去问学院的老师。不问就不是问题,问了就成了问题。希望大家能好好分辨信息的可靠性,不要见风是雨,搞得人心惶惶的。 吐槽了那么多,我也在想怎么解决论文格式这个大难题。我觉得写作应该遵循「内容与样式分离」。什么是内容与样式分离?举个例子,论文的一级标题格式是居中加粗四号宋体,我现在要写两个标题,分别是「翻译过程」和「案例分析」。 「内容与样式分离」的做法是这样的: 设置「标题 1」样式 居中 加粗 四号 宋体 输入「翻译过程」 把「翻译过程」设置为「标题 1」 输入「案例分析」 把「案例分析」设置为「标题 1」 「内容与样式不分离」的做法是这样的: 输入「翻译过程」 设置「翻译过程」的格式 居中 加粗 四号 宋体 输入「案例分析」 设置「案例分析」的格式 居中 加粗 四号 宋体 感受到两者的差距了吗?「内容与样式分离」会减少重复劳动。「内容与样式分离」就是定义样式,再把样式应用于内容,这样就不需要写一个标题就调一次格式。在毕业论文这件事上,我觉得可以用文档转换器 pandoc 来实现「内容与样式分离」。 新建一个模板文档(template.docx) 1 pandoc -o template.docx --print-default-data-file reference.docx 把模板的「标题 1」的样式设置为「居中加粗四号宋体」 新建一个空白文档(input.docx) 在空白文档填写「翻译过程」,并将其设置为「标题 1」。 把模板的「标题 1」样式应用于空白文档。 1 pandoc input.docx -o output.docx --reference-doc template.docx 现在打开输出文档(output.docx),你会发现「翻译过程」已经变成了「居中加粗四号宋体」。 铺垫了那么多,终于要说解决格式问题的办法了。学院负责制作模板,打包 pandoc 和转换文档的脚本。学生只管写,写完后打开脚本让 pandoc 负责排版。这样学生和导师都可以关注于内容,而不是纠结格式,甚至还可以用 Markdown 写论文。 其实我觉得写论文还是用 R Markdown 最省心。理科生要输入数学公式,所以会用 LaTeX,那再迁移到 R Markdown 也不是难事。可我们文科生好像没有必须不用 Word 的理由,估计还得在 Word 的泥潭里躺一万年。

2021/4/25
articleCard.readMore

/æ/ 在美式英语的 3 种发音

/æ/ 在美式英语中有 3 种发音: 正常发音,舌头抵住下齿,咧嘴,发类似 /ɑː/ 的音。示例单词:back(点击 US 旁边的喇叭可以听录音)。 /æ/ 加上 /n/、/m/ 时,会变成 /e/,也就是 /æn/ -> /en/、/æm/ -> /em/。示例单词:land。 /æ/ 加上鼻音 /ŋ/ 时,会变成 /eɪ/,也就是 /æŋ/ -> /eɪŋ/。示例单词:gang。 /æ/ 加鼻音会发生变化的现象叫做 /æ/ raising。 American English - AA [æ] Vowel - How to make the AA Vowel - YouTube(哔哩哔哩)这个视频演示了 3 种发音。 我的发音是跟着《赖世雄美语发音》学的。这本书讲解质量高,但是没讲 /æ/ 加鼻音时的变化,真是可惜。于是我就写了这篇文章作补充。

2021/4/13
articleCard.readMore

随想

本文用于记录难以成文但值得分享的内容,不定时更新。 # # 给 config.toml 的 archivePaginate 设置一个很大的值(比如 99999),这样存档页面就不会分页了。 # # 泡干香菇时,干香菇总是浮在水上,让我很头疼。现在发现了一个让干香菇完全浸泡在水里的方法。 放香菇到碗里 倒满热水 反扣汤锅锅盖到碗上 # 鸡胸肉高蛋白,低脂肪,是有营养的食物,但就是吃起来啃纸一般。最近发现了两个拯救改善鸡胸肉口感的方法——用肉锤把肉锤烂、加淀粉。这两个方法可以一起用,先把肉锤烂,再放淀粉。 # # 阿斯巴甜是甜度高热量低的甜味剂,可用于代替食糖,从而减少热量摄入。阿斯巴甜很适合减脂/健身人群。我称之为人类伟大的发明、神奇的化学物质、减脂伴侣。阿斯巴甜真的超甜,用的时候先放一点点试试味道。如果放一勺下去可能会甜死。 # # Linux 版的 Edge 浏览器现在可以登录微软帐号,侧面标签页的功能超级好用,而且不翻墙也能装插件。现在 Edge 已经是我的主力浏览器了。 # # 当孩子需求和父母认为的不一致时,父母还执意以自己的方式对孩子好,这就成了自我感动。对一个人好,就应该以他希望的方式,而不是自己认为的方式,或是社会公认的方式。 父母以一种自我牺牲的方式对我好的时候,我很难接受这种好。首先,我不需要这种好。第二,我会有亏欠感。我感觉压力太大了,我可不希望父母做让自己不舒服的事情。良好的关系,应该是轻松舒适的。 # # 今天在 Namecheap 上续费域名,在谷歌搜 namecheap renewal coupon 就找到个减 20% 的优惠券。之前买域名的时候好像没用优惠券,真亏。

2021/4/1
articleCard.readMore

单身狗

单身是个中性的词,而狗除了指动物以外的定义都是贬义。 即犬 十二生肖之一,配地支的“戌”。 比喻坏人。 奉承,巴结。 詈词。表示极端鄙视。 ——《现代汉语大词典》 当单身遇上狗,单身也就笼罩着一层贬义的色彩。但是,贬义也不是绝对的。对于爱狗人士来说,狗是可爱的动物,反而变成褒义词了。英文中和狗相关的用法也比较正面,如 lucky dog(幸运儿)。 十年前听到单身狗这个词的时候,感觉还挺有趣,自称单身狗就是单身人士的幽默。但是现在越听越不喜欢。首先,我不能理解为什么要给自己贴上贬义的标签。反正我不以单身狗自称,我不想贬低自己。其次,我不能理解为什么有人见到情侣就要自称单身狗,仿佛自我贬低还有种快感。 谈恋爱之后我就更不喜欢单身狗这个词了。有时候同学说我在撒狗粮1,我听了就觉得特别尴尬,仿佛我牵着女友的手都伤害了单身的同学。要是我亲女友一口,那有些同学岂不是要洗眼睛了。也许自嘲的人是有些嫉妒吧。当一个人自称单身狗时,看似自嘲,但其实有些攻击性。 后记:我讨厌单身狗一词可能是因为我太严肃了,总是咬文嚼字。说单身狗的人不见得有恶意,只是觉得好玩。 撒狗粮的意思是「情侣在单身人士面前表达爱意」。与其对应的词是吃狗粮,意思是「单身人士看到情侣表达爱意」,喂吃狗粮亦适用于恋爱人士。 ↩︎

2021/3/21
articleCard.readMore

动漫这个词不能再用了

动漫最初的意思是「动画和漫画」,出自 1998 年创办的中华动漫出版同业协进会与 1998 年创刊的动漫杂志《动漫时代》。我也是坚定地认为动漫的意思是「动画和漫画」。 2015 年的时候,有次听同学说动漫是大人看的(动画),动画是小朋友看的。我听到动漫的这个定义的时候十分震惊,动漫居然可以指深刻的动画。根据我最近的观察,动漫目前最流行的意思是动画,并不是深刻的动画。 我觉得赋予动漫一个新定义的行为完全不可理喻。接下来我说的原义是「动漫=动画+漫画」,新义是「动漫=动画」。首先新义和原义有冲突,会让人造成误解。其次,新义不符合语言习惯。原义的「动」「漫」二字是从「动画和漫画」里摘取出来的,这种缩写是符合语言习惯的。但是我真的不理解新义是怎么回事,难不成动漫是「会动的漫画」,但动画不一定是从漫画改编的。 最近上网发现不符合语言习惯的新义居然是最流行的,还有衍生词:国漫(国产动画)、日漫(日本动画)。看到国漫和日漫,我第一反应就是漫画,真的想不到是动画。创造国漫一词的人不会想到国产漫画的缩写也是国漫吗?自从新义流行后,关于动画和漫画的词真的是越来越混乱了。哪怕现在多数人觉得动漫就是动画,我也不能接受这个定义。 现在动漫有两个意思了,我还是要说:「动漫的意思应该是动画和漫画!」 我只好放弃用这个有歧义的词,改成说动画和漫画。我觉得交流用通俗大众的词语更好,造新词会增加交流成本。例如,大家都知道动画、日本动画、国产动画的意思,但是番剧、日漫、国创就不见得人人都懂。

2021/3/21
articleCard.readMore

凉粉、烧仙草和龟苓膏的区别

总结:凉粉、烧仙草和仙草冻是同一种食物,龟苓膏则是另一种食物,它们都是黑色凝胶。凉粉不苦,原料是草本植物仙草、薯粉/淀粉。龟苓膏苦,正统龟苓膏的原料是龟板、土茯灵、甘草等中药材。 左边是仙草冻,右边的是龟苓膏 今天去超润甜品店买糖水给女友喝,去买的时候突然想起了一个我纠结很久的问题:凉粉、烧仙草和龟苓膏看起来都很像,它们到底有何区别。到了超润甜品,先点了女友要的椰汁红豆仙草西米和炸馒头。然后我翻遍了菜单,发现没有凉粉,就打包了烧仙草和龟苓膏,打算回家后边看维基百科边吃。不过转念一想,既然来了店铺,为何不直接问店员呢,他们才是最懂行的啊。吃了那么多年,实在是不想吃得不明不白,我就问了店员姐姐。 我:请问凉粉、烧仙草和龟苓膏有什么区别? 姐姐:凉粉就是(烧)仙草,龟苓膏是另一种食品,龟苓膏是苦的。 (姐姐耐心地科普……) 姐姐:你是哪里人? 我:我广东的。 姐姐:广东人都唔知,我打死你,你唔饮糖水咩?(广东人都不知道,我打死你,你不喝糖水吗?) 没想到被嘲讽了,这居然是广东人的常识! 我:那你们店的烧仙草和龟苓膏是自己做的还是买到现成的? 姐姐:你家的饭是什么做的? 我:用米煮的。 姐姐:那不就是咯,我们也是买原料回来自己做的。 又被嘲讽了…… 不过姐姐人挺好的,拿了两个杯子分别舀了几勺烧仙草和龟苓膏给我,让我试一试。它们看起来真的没什么区别,吃起来口感也差不多,但味道就有差别了。仙草有点甜,龟苓膏则是有点苦。回家之后看了维基百科的相关条目,再结合姐姐的科普,整理了一下三者的区别。 龟苓膏 凉粉/烧仙草/仙草冻 形状 黑色凝胶 黑色凝胶 味道 有点苦 有点甜 原料 龟板、土茯灵、甘草等中药材 仙草、薯粉/淀粉 左边是仙草冻,右边的是龟苓膏 左边的是台湾烧仙草,右边的是龟苓膏 简单来说,凉粉和烧仙草是同一种食物,龟苓膏则是另一种食物。不苦的黑色凝胶叫仙草冻,又称凉粉1、烧仙草2,原料是草本植物仙草、薯粉/淀粉。苦的黑色凝胶叫龟苓膏,正统龟苓膏3原料是龟板、土茯灵、甘草等中药材。烧仙草还有另一种形态——台湾烧仙草,即仙草冻加奶茶、红豆、绿豆、芋圆、花生等配料。 要感受凉粉、烧仙草和龟苓膏的区别,最好还是去糖水店点来吃,可以仔细观察和感受,还可以和店员交流。一定要记住,如果店员问你是哪里人,千万别说是广东人。 # 烧仙草 - 维基百科,自由的百科全书 龟苓膏 - 维基百科,自由的百科全书 北方有种白色的食物也叫凉粉,以大米、豌豆或绿豆为主要材料制作而成。为了和北方凉粉相区别,仙草冻又称黑凉粉。 ↩︎ 仙草冻还叫仙人粄和草粿。 ↩︎ 我之前吃过的王老吉龟苓膏,成分表里面有凉粉,看来龟苓膏也可能加有凉粉。 ↩︎

2021/3/15
articleCard.readMore

让 Hugo 自动给图片加上说明文字

本文测试于 Hugo extended 0.125.6,完整的网站代码在此。 # Markdown 插入图片的代码是这样的: 1 ![描述](链接 "标题") 对于的 HTML 代码: 1 <img src="链接" alt="描述" title="标题" /> 用户的光标放在图片时,会有提示框,其内容为标题。提示框不好用,因为用户不一定会把光标移动到图片上,而且用户可能不用鼠标。 既然提示框不好用,那我们可以将标题转换为图片底下的说明文字,这样用户一定会看到。对应的 HTML 代码为: 1 2 3 4 <figure> <img src="链接" alt="描述"> <figcaption>标题</figcaption> </figure> 配置流程: 在博客根目录下新建 layouts/_default/_markup/render-image.html 1 2 mkdir layouts/_default/_markup/ -p touch layouts/_default/_markup/render-image.html 往 render-image.html 填入以下内容(如果不需要修改样式,可以去除 class="..."): 1 2 3 4 5 6 7 8 9 10 {{ if .Title }} <figure class="figure"> <img class="img" src="{{ .Destination | safeURL }}" {{- with .Text }} alt="{{ . }}"{{ end -}} > <figcaption>{{ .Title }}</figcaption> </figure> {{ else }} <img class="img" src="{{ .Destination | safeURL }}" {{- with .Text }} alt="{{ . }}"{{ end -}} > {{ end }} ![](https://upload.wikimedia.org/wikipedia/commons/1/1f/Wiki-sisters.png "维基娘的姊妹们(由左至右):维基共享资源娘、维基百科娘、维基语录娘") 会显示成这样。 如果不需要说明文字,就写 ![维基娘的姊妹们(由左至右):维基共享资源娘、维基百科娘、维基语录娘](https://upload.wikimedia.org/wikipedia/commons/1/1f/Wiki-sisters.png)。 # 不推荐此方法的原因是 <img> 元素的 alt 属性(描述) 和 <figcaption> 元素意义不同,将前者转换成后者是错的。 如果你的 Markdown 图片链接是只有描述没有标题,也可以把描述变成说明文字。render-image.html 需要改为: 1 2 3 4 <figure class="figure"> <img class="img" src="{{ .Destination | safeURL }}" alt="{{ .Text }}"> <figcaption>{{ .Text }}</figcaption> </figure> ![维基娘的姊妹们(由左至右):维基共享资源娘、维基百科娘、维基语录娘](https://upload.wikimedia.org/wikipedia/commons/1/1f/Wiki-sisters.png) 会显示成这样。 # 我给本站加了一些额外的样式,你可以根据你的需求调整你的网站。!important 必要时才用。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 /* remove figure margin */ figure { margin: 0 !important; } figure > figcaption { color: gray; } /* image is not clickable because photoswipe is disabled */ p > img { cursor: auto !important; } /* center img */ // :has only works for browsers after December 2023, see https://caniuse.com/css-has p:has(.img), .figure{ text-align: center; } # 我还在 Stack Overflow 发现了一个怪招:使用单列双行的表格,第一行放图片,第二行放说明文字。 1 2 3 |![](图片链接)| |:-:| |说明文字| 1 2 3 | ![](https://www.storywarren.com/wp-content/uploads/2016/09/space-1.jpg) | |:--:| | Space | # Caption images with markdown render hooks in Hugo | Sebastian De Deyne Image render hooks | Hugo html - Accessibility - Difference between <img alt> and <figcaption> - Stack Overflow Alt vs Figcaption <img>: The Image Embed element - HTML: HyperText Markup Language | MDN <figure>: The Figure with Optional Caption element - HTML: HyperText Markup Language | MDN

2021/3/11
articleCard.readMore

女生节、妇女节和女神节

昨天是 3 月 7 日,有人在大学的群里发红包庆祝女生节,这我才发现女生节到了。上网维基看了看女生节的条目,发现女生节的日期是 3 月 7 日,刚好是妇女节的前一天。根据我在大学的观察,女生节的庆祝方式一般就是男生们买礼物给女生们,或是男生们表演节目给女生们看,以表达男生对女生的关心。大学生似乎对此习以为常,不过我总感觉不对劲。我认为女大学生就是独立个体了,为什么还需要特别关心呢?女生真的享受这种关心吗?我感觉这个节日有种对女性的歧视,仿佛女生是弱势群体,需要特别照顾。反过来,我在男生节收到礼物感觉是无功受禄,受之有愧。收了男生节礼物实在是不好意思,只好在女生节也送礼物给女生。 今天是妇女节,又称国际妇女节、三八国际妇女节、国际劳动妇女节,英文是 International Women’s Day。妇女节是纪念妇女为争取政权、男女平等所获成就的国际性节日。妇女节是值得纪念的节日,不过今天大学的微信群没人发红包庆祝妇女节了,也没人发信息庆祝妇女节,好像大家都不大在意呢。翻朋友圈,发现了有趣的现象。有四五条动态用女神节或女王节表示庆祝,只有一条动态用妇女节这个词。看来大家知道这个节日,但似乎不喜欢妇女这个词。我觉得不喜欢的原因是妇女听起来像家庭主妇(专做家务而无职业的妇女),家庭主妇经济上依附于丈夫,而且可能年纪较大。我们的社会文化存在对女性的年龄歧视:年轻女性更有价值,年长女性更没价值。所以女性害怕被贴上年纪大的标签。其实现代汉语大词典中妇女的定义是「成年女子的通称」,不过在现实使用的时候倒是有家庭主妇的感觉。 至于女神节和女王节,这是商家把妇女节变成购物节的手段,皆在鼓励女性消费。女神和女王,听起来高高在上的,完全和男女平等不沾边。1857 年 3 月 8 日,美国纽约的制衣和纺织女工走上街头,抗议恶劣的工作条件和低薪。3 月 8 日,这曾经是女性抵抗资本家的日子,现在资本家却把它变成了用以谋利的购物节。唉,我只能骂一句:「我呸!」 既然妇女可能包含年龄歧视,女神节和女王节又偏离了妇女节的原意。那该怎么说呢?中国人见面总不能来一句「Happy women’s day」吧。我觉得可以把 Women’s Day 译为女性节或女人节,女性和女人都是中性词。女人还有妻子的意思,所以可能女性这个词会好些。张佳玮把 Women’s Day 译为女节,这个译法更为简洁。 后记:妇女节是国家假期,妇女放假半天。

2021/3/8
articleCard.readMore

为自己而活

现在是凌晨四点十三分,我又失眠了。脑海里闪烁着白天和亲戚的对话。 (我目前大四。) 亲戚:你实习了吗? 我:没,不打算实习了。我不喜欢现在读的英语专业。打算毕业后学一年计算机,我对计算机感兴趣。 亲戚:你学计算机也没个确定的方向,学半年之后又不喜欢怎么办?不如先实习,积累一下工作经验。 啊,这话听了真他妈难受。虽然也不是第一次听了,但每次听到还是很难受。「如果学了新东西可能有一天不喜欢了,那还不如从事所学专业的工作」这算什么狗屁道理。我读了三四年英语专业,经过深思熟虑,最终承认了自己不喜欢这个专业,决定毕业后自学一年计算机。目前才刚刚开始不久,就直接被判了死刑,奉劝我去做百分百讨厌的英语工作。但实际上,不试试看,鬼知道喜不喜欢啊,未来的事情难以预测,还才开始没多久就被否定了的滋味真他妈难受。 从我出生开始,仿佛都是被社会期待推着走的,我有几分几秒是为自己而活呢?我就像一个木偶,在社会拟定的人生脚本下演出。小学的任务是做功课;初中的任务是考高中;高中的任务是考大学;大学的任务是拿学位证;毕业后的任务是找工作。填高考志愿算是第一次为自己的人生作选择吧。本来我是想去广东药科大学读康复治疗专业,不过高考分数只能让我读一所民办本科学校,不能选择心仪的学校,结果就去了民办本科学校读自己擅长的英语,现已验证第一次的人生选择并不如人意。 本以为上了大学之后,没有高考这种特定目标会轻松些许,但实际上大学生活并不是一个自由的状态。首先,大学里有不少浪费时间的杂事。其次,读大学依然有「特定任务」:好好听课,不能挂科,考过英语专业四级和八级1。一开始我也是这样做的,可是我慢慢地开始觉得越来越没劲。按照学校的安排去听课和考试,跟读中学也没什么区别。英语专业的主要课堂内容就是文学,而我也不喜欢文学。我是一个很讨厌做题和考试的人。大二下学期为了备考专四,我练了一段时间的听力训练,居然还做了十套试卷。其实我内心并不是特别想考专四,只不过看到大家都在准备着,我也就随大流了。随之考完专四后,我在学业上突然没了目标,接着就抑郁了一个月。 大二下学期,发现自己不喜欢本专业之后,感到很迷茫,也不知道自己该做什么。后来我内心有个声音叫我去学编程,大概是因为我曾经喜欢过编程吧,初中的时候还学过一个星期的 AutoIt v3,当时觉得十分有趣。不过那时发现了自己都不认识 local 和 global ,感觉学起来很费劲,所以就先去自学英语。花时间学习英语之后,初中英语成绩提高了不少。迫于学业压力,久而久之就忘记了学英语的初衷是能够轻松地学习编程。 在大三上学期的某个凌晨,我失眠了,就去看知乎和哔哩哔哩来打发时间,结果越看越无聊。然后我就打开存放许久的 Python 教程,搭建好环境之后写下 Hello World,突然那种有趣的感觉又回来了。接着我去学了半本 Python Crash Course, 2nd Edition 之后又学了 Python for Everybody,依然觉得有趣。这是我人生中重新拥有了自己喜欢做的事情,学了编程之后就很少再有平日里那种抑郁的感觉。我发现计算机科学是个很适合自学的科目,GitHub 上就有个学习路线。于是和家人商量,打算毕业后自学一年计算机,尝试去做个程序员。 按照学习路线上课之后我又开始觉得没劲了,这不就上大学的课程吗?又回到那种按部就班的状态了。于是我放弃了学习路线,对什么感兴趣就做什么,学了些杂七杂八的东西:Markdown、HTML、Git、LaTeX、R Markdown2。还用 blogdown 搭建了博客,2020 年 11 月 1 日发布了第一篇文章。我就这样拥有了第二件喜欢做的事情:写博客。要是没有前面的尝试,我就不会发现我喜欢编程和写作,尝试还是很重要的。 不过我还是很担心自学一年的编程水平不足以让我成为一个程序员,可能又因为长时间放下了英语而找不到英语工作。啊,我又陷入了毕业后必须找工作的人生脚本了。写下这段我才发现自己对工作有些执念:先选择自己喜欢的,不行再考虑熟悉的英语。其实工作那么多,也不用吊死在一棵树吧。编程作为一个兴趣爱好也不错啦。 要我一直做不喜欢的事情,我会抑郁,我就是这样的人。所以我不想再为别人的期待而活了,不想再过那种抑郁的生活了。现在也不想设立什么学习目标了,毕业后的一年就随心所欲做所有感兴趣的事情吧。我想为自己而活,哪怕一年也好。尝试一年后,如果能以喜欢的事情为职业就最好了,实在不行才做其他。最后,引用《不能承受的生命之轻》的一段话作为结尾吧,它代表了我的心声。 人永远都无法知道自己该要什么,因为人只能活一次,既不能拿它跟前世相比,也不能在来生加以修正。没有任何方法可以检验哪种抉择是好的,因为不存在任何比较。一切都是马上经历,仅此一次,不能准备。 所以,对于我来说,在当下经过思考的决定就是最好的。 专四专八是英语专业的等级考试。专四是大二下学期(第四学期)考的,专八是大四下学期。专四专八一生最多考两次,第一次考不过,下一年可以重考。 ↩︎ 现在看来,其实不是杂七杂八的东西,它们都是写作工具。或许无论我再怎么做不喜欢的事情,内心还是会默默地把我引导到喜欢的事情上。 ↩︎

2021/2/18
articleCard.readMore

催生的恶果

昨天听了故事 FM 的第 458 期节目《拉拉自述:和直男接吻后,我决定再也不相亲了》。故事讲述人小A今年 29 岁,生活在贵州贵阳,是一名中学老师,是女同性恋者。 一开始小A和讲述了和女友小柚的甜蜜故事,后来发现小柚已经结婚,还有另一位女朋友,于是她们最后分手了。小A为了确认自己会不会对男生有好感,就去相亲,认识了一位理工男。答应和理工男恋爱后,男友和小A亲吻,小A不喜欢,就推开了男友。男友洗完澡穿着内裤出来,小A看了看,觉得男人的身体没有美感。和男友同床睡觉时,男友的鸡鸡顶着小A,小A觉得特别恶心。就这样小A确定了自己就是女同性恋,和男友分手了。 小A家比较传统,父母绝对不会接受小A出柜。为了不伤害父母,小A选择形婚。小A和认识十几年的 gay 朋友结婚了。婚后两人住一套房子,互不干涉。有天小A心情不好,男方妈妈给小A准备的丰盛的晚餐,都是小A喜欢的食物。看着老人如此忙碌,小A觉得要把这个善意的谎言圆下去。 听完这个故事,感觉故事里的每个人都是受害者,为每一个人感到难过。小A为了满足父母对结婚的要求,不得已撒了个弥天大谎。理工男到分手那一刻也不知道为什么自己的初恋还没维持一天。Gay 的母亲并不知道小A和 Gay 的婚姻是形婚。 我觉得这场悲剧的源头就是「传宗接代」的观念了,要是小A的父母不要求小A结婚生子,那就没有这场悲剧了。一部分人不生小孩,人类也不会灭绝啊。对于部分国人来说,「传宗接代」似乎是和「地球围着太阳转」一样不容置疑。你问他们「为什么一定要生儿育女」,他们会说「这就是很自然的一件事啊」。我觉得结婚和养小孩真的是很严肃的事情。小孩不是生下来就行了,养小孩需要花费大量的金钱和精力,并且还得养十八年。如果结婚和养小孩不能给自己带来快乐,那就别做,只为了满足父母去生小孩,到头来委屈的还是自己。自己的感受最重要,一定要遵从自己内心的感受。说到底,对自己负责的只有自己,往父母挖的坑里面跳了,最后还得自己爬出来,他们是没办法给你逝去的青春负责的。

2021/2/6
articleCard.readMore

在哔哩哔哩看未删减动画

2021-02-18 更新:哔哩哔哩港澳台动画仍然有些是删减版的,我现在改用巴哈姆特动画疯看动画了,终于不用担心删减和下架了。会员价格是每月 99 新台币(22.8 人民币)。不开会员也能看所有动画,只是看 30 秒广告,然后可以看 720P 画质的动画。不过不开会员就不能通过年龄验证,可能有些动画看不了。所以最好还是开通一次吧。 在国内看动画最头疼的就是审核问题,但凡动画有点血腥暴力或是色情就难逃广电总局的魔掌了。轻则删减,重则下架。不过我发现哔哩哔哩的港澳台区域动画是未删减的,所以我现在会优先考虑看港澳台动画。使用国内网站直接打开港澳台动画是没法看的,不过我们可以直接到港澳台使用哔哩哔哩客户端把动画缓存下来。哈哈,开个玩笑。其实我想说的是怎么绕过区域限制。有几个绕过区域限制的方法,分别是翻墙、使用哔哩哔哩 UWP、使用脚本程序。 # 使用翻墙软件翻墙到港澳台就可以直接看港澳台动画了,这个方法最靠谱。 # 打开 Microsoft Store,搜索「哔哩哔哩 UWP」,安装由逍遥橙子开发的「哔哩哔哩 UWP(第三方)」。打开哔哩哔哩 UWP直接就能看港澳台动画了。以前是可以直接看港澳台动画,现在显示的某些民间汉化组资源,应该也是未删减的。 # 注意,用脚本的默认接口已无效,测试于 2021 年 2 月 2日。目前要用脚本应该只能使用自定义代理服务器了,请参考解除B站区域限制的文档。 用脚本之前要先安装脚本管理器,打开 Tampermonkey 官网进行安装。接着安装解除B站区域限制或者Bilibili 港澳台。开启其中一个脚本,翻墙登陆 B 站打开港澳台动画就能看了。

2021/2/2
articleCard.readMore

轻松安装 Python 和 Python 包

安装 # Python 新手遇到的第一个问题就是安装 Python,我看好多教程都推荐到官网下载。这当然是正确的做法,不过还有更简单的方法。 # 在 Win 10 安装 Python 特别简单,直接在 Microsoft Store 搜索 Python 就可以安装最新版本。注意,软件开发者是 Python Software Foundation。安装好之后在 Command Prompt 输入 Python 就可以使用了。 如果你用的是 LTSC 版本,就点击这里下载 Microsoft Store 安装包。如果是 LTSB 就点击这里下载安装包。如果你用 Win 10 之前的 Windows,就安装 Miniconda 吧,参考下面的用法。 # 在 Linux 发行版一般都自带 Python,可以直接用。比如 Ubuntu 20.10 就自带 Python 3.8.6。不推荐采用源码编译,源码编译可能会覆盖系统自带的 Python。如果要用最新版的 Python,就先安装 Miniconda,再创建虚拟环境: 1 2 conda create --name py3.9 python=3.9 # 创建包含最新 Python 3.9 的环境 conda activate py3.9 # 激活环境 取消激活的命令是: 1 conda deactivate 取消自动激活环境的命令是: 1 conda config --set auto_activate_base false 如果你从事计算科学的工作,可以直接安装包含相关软件包的 Anaconda。其实 Miniconda 也可以安装 Anaconda 包含软件包: 1 2 conda create --name ana anaconda # 创建包含 Anaconda 所有软件包的环境 conda activate ana # 激活环境 # 咱们大中华局域网连接 Internet 时,时而断线,时而速度慢。这时候就可以给 conda 和 pip 设置国内的镜像源,速度马上就飞起来了。 # 下面用的是清华镜像站的 pypi 镜像。 临时使用: 1 pip install --index-url https://pypi.tuna.tsinghua.edu.cn/simple some-package 设置为默认: 1 2 3 # 先升级 pip 再配置 pip install --index-url https://pypi.tuna.tsinghua.edu.cn/simple pip --upgrade pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple # 下面用的是清华镜像站的 Anaconda 镜像。 先建立文件: 1 2 conda config # 生成配置文件 nano ~/.condarc # 编辑配置文件 然后把下面的内容复制到 .condarc: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 channels: - defaults show_channel_urls: true default_channels: - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/r - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/msys2 custom_channels: conda-forge: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud msys2: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud bioconda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud menpo: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud pytorch: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud simpleitk: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud 最后运行 conda clean -i 清楚缓存,确保用的是清华源的索引。 # 我们可以用 pip 和 conda 安装 Python 包。 # 从 Microsoft Store 安装的 Python 自带 pip,Linux 的话就用自带的包管理器安装。 1 sudo apt install python3-pip 检查一下 pip 是否安装成功: 1 2 $ pip --version pip 21.0.1 from /home/xxxx/.local/lib/python3.8/site-packages/pip (python 3.8) 有显示结果就是安装成功了。运行 pip --help 可以查看帮助,下面介绍几个最常用的命令。 查找 1 pip search you-get 如果无法搜索的话,可以直接打开 Python Package Index 搜索。 安装 1 pip install you-get 可以同时安装几个软件,用空格隔开就可以了。卸载和升级也可以作用于多个软件包。 1 pip install you-get youtube-dl 升级部分包 1 pip install --upgrade you-get 升级所有包 pip 没有升级所有包的命令,要升级所有包,就得用 pipupgrade 或者其他同类工具。先安装 pipupgrade: 1 pip install pipupgrade 然后就可以用它升级所有包了: 1 pipupgrade --ignore-error --yes --verbose 列举已安装的包 1 pip list 卸载 1 pip uninstall you-get # 运行 conda --help 可以查看帮助,安装、卸载和升级同样可以作用于多个软件包。 查找 1 conda search pandoc 安装 1 conda install pandoc 升级部分包 1 conda update yaml 升级所有包 1 conda update --all 列举已安装的包 1 conda list 卸载 1 conda remove pandoc # conda 官方手册 清华大学开源软件镜像站

2021/2/1
articleCard.readMore

诗婷

偶遇 # 不记得是高二下学期还是高三上学期,我突然右脚大拇指痛,于是去康复科看。医生诊断完就给我开单子,我拿着单子瘸着走出去。刚走出去就遇到一个医生姐姐,看起来像是大学刚毕业的。她关心地问我:「你有什么问题?」我就说了一下脚趾痛的问题。我也算是医院的常客了,遇到的大多数医生一般都是问症状,开单子,很少会关心病人。突然被医生姐姐关心一下,而且我还不是她的病人,我感觉既意外又高兴。 出了诊室,看了看墙上贴着的员工表,原来刚刚的医生姐姐叫诗婷,是康复治疗师。拿着单子缴费之后我就回去给脚做电疗。因为当时我对运动学感兴趣,做完电疗就去问她运动学的问题,她也很耐心地给我讲,感觉她是个很友善的人。接下来几天还要做电疗,每次做完电疗就找诗婷聊聊天,不过我不太记得具体聊过什么了,大概是高中生活的糟心事吧。就记得诗婷很有同理心,很能理解我。我们还互加微信好友,交换了手机号码。高中的我敏感、自卑、朋友少1,很多情绪都是埋在心里,不曾向外人诉说,能有诗婷这样理解我的人真的十分开心。我和诗婷见面的次数可能还没有十次,但是她给我带来的影响却不小。在这记录几件记忆深刻的事吧。 # 有次我在微信问诗婷解剖学问题,我问的第一个问题,诗婷是有回答的。接下来的问题,诗婷就没有直接回答,反而说:「你不读相关书籍的话,我现在解答了这个问题,下次你还是不懂。」一开始听到这话我是觉得不舒服的,感觉很惭愧。可能这就是忠言逆耳吧。这种惭愧感一直在我心里,因为我也没怎么读解剖学的书,所以就没再问那些问题了。不过诗婷说得也对,我没怎么读解剖学教材就来问,她回答了,我也是一知半解。作为一个求知者,还是要有这种惭愧感,尽量不提愚蠢的问题,不要浪费别人的耐心。 探索一个问题,没去查资料就去问别人,不就是大家嫌弃的伸手党吗?后来我学了编程,读了《提问的智慧》(How To Ask Questions The Smart Way),也看了网上很多提问帖,才深刻地意识到不寻求答案就问别人,往往会问出一些过于宽泛的问题,浪费别人的时间。如果在网上提了一个糟糕的问题,可能别人会忽略或者教育你,最严重的就是骂你。所以提问前最好先自己去尝试寻找答案,让别人看到你是个主动的人,这样别人更愿意帮你一把。刚刚提到的《提问的智慧》是一篇很好的提问指南,虽然讲的是计算机的问题,不过里面的思想还是通用的。 # 高三的时候感觉心理压力特大,想去看心理医生。在家试探性地问爸妈,我爸妈很嫌弃,他们觉得(电视剧那种疯疯癫癫的)神经病才需要去看心理医生。我就特别苦恼,最后鼓起勇气给诗婷打了个电话2。我就说了我想看心理医生,说出了我的纠结,问她有什么建议。她就鼓励我去试试看。那通电话聊了好久,可能有一两个小时,诗婷一直耐心地听。沉默的时候我感觉很尴尬,害怕诗婷说「没事就先挂了」。不过诗婷也没说那句话,直到我把想说的都说完了,我才挂的电话。打完电话心都是暖暖的。我从未料想过有人会听我讲一两个小时的话。这样的倾听本身就很治愈,也减轻了我对看心理医生的羞耻感。现在想起来,感觉诗婷就像《窗边的小豆豆》3里面的小林校长,会耐心地把话听完。 我没和爸妈打招呼就自己去看心理医生了,跟医生说了我会用手抠指甲4和捏耳朵,严重时还会弄出血,然后做了几个心理量表。诊断是焦虑症和强迫症。原来抠指甲、捏耳朵叫强迫行为,是强迫症的一种症状,另一种症状叫强迫观念。医生说这些强迫行为是用来缓解焦虑的。看到这个诊断的时候,我不是伤心,而是感觉心里有块石头落地了,我从小学就有的强迫行为终于能治了。 高三的时候我还有个特别奇怪的强迫症状:一学习就咳嗽。当时可能是压力太大了,焦虑情绪加重,出现了躯体化的症状。当时,一去上课就会不断咳嗽,晚上回到宿舍(看到同学在挑灯夜读)也会不断咳嗽。发展到最后就是看书就咳嗽,完全没法复习了。于是我就不去上课了,在学校对面租了个房子自己待着,有时回学校拿复习资料,月考的时候才回去。一看书就咳嗽实在是太难受了,很难复习,所以高三我就只复习了比较喜欢的英语和生物。我以为我就只能读个专科了,最后考了个民办本科,对高考结果还挺意外。 其实咳嗽的问题我从高一下学期进了重点班就有了,一直去医院看,但一直治不好。要不是去看了心理医生,咳嗽都成绝症了5。想想都觉得后怕。真是多亏诗婷的鼓励。 # 认识诗婷没多久,她就要结婚了。她也邀请了我去喝喜酒。能被邀请还是蛮开心的。我当时还准备了一封五十块的红包。刚去的时候也不知道该坐哪一席,诗婷就请接待员带我去和她妹妹坐一桌。感觉自己特别受重视。谁知坐着坐着就有接待员过来问我是哪边的亲戚,我说我是诗婷的朋友,然后接待员就把我带到诗婷同事的那一桌。不过这样也挺好的,我在那桌还遇见一位同乡的医生姐姐。一开始发现谁都不认识,感觉怪尴尬的,后来有个认识的人就没那么尴尬了。在那第一次吃到龙虾,超好吃6。喝完喜酒离开后我才发现我忘给红包了,真是十分遗憾。 # 刚上大学的时候觉得大学的糟心事太多了,比如浪费时间的素质培养计划和无聊的政治必修课。遂与诗婷吐槽这大学生活和想象的完全不一样。诗婷回复:「那你觉得大学是怎么样的呢?」我就愣了一下,思考了一下。我以为的大学生活是课业不多,有充裕的时间干其他事,但现实就是大学也有不少我讨厌的事情。看来我很容易以为自己的想法就是真相,然后发现大学它不是这样,现实证明了我的想法是错的,打击了我的自恋感。但这样的抱怨也于事无补,还不如学着在大学摸鱼呢。 # 我一直很感激诗婷对我的帮助。过年的时候我都会发新年祝福给她7,也会寒暄几句。可是几年过去了,好像祝福语都用完了。和朋友保持关系对我来说一直是个难题,要是不见面似乎在微信也不知道聊啥。或许,相见不如怀念吧,把回忆化作文字记录也挺好的。 本文发布前就发给诗婷看了,这是她的回复: 看完你对我的描写觉得心里非常暖,没想到自己不经意的举动会对你有帮助,谢谢你。希望你越来越好。到时候毕业工作了一定要记得和我分享你的喜悦。 高中只是个时间限定词,其实我现在还是敏感、自卑、朋友少,不过不会因此而那么苦恼。 ↩︎ 我给谁打电话都特紧张,打电话对我来说真的是很需要勇气的事情。 ↩︎ 《窗边的小豆豆》讲述了小豆豆上小学时的一段真实的故事。小豆豆因淘气被原学校退学后,来到巴学园。小林校长听小豆豆吧啦吧啦讲了四个小时的话。在这期间,小林宗作校长不但没有丝毫的厌倦和不耐烦,反而一边点头一边询问:「还有呢?」,最后直到爱讲话的小豆豆没有话可讲。 ↩︎ 我表舅听闻了我的症状,对我说:「抠指甲也挺好的,都不需要指甲钳了。」我听了这个说法感觉很放松,原来抠指甲还有这等好处,换个角度思考,这件事就变积极了。 ↩︎ 看了两年多的心理医生都没完全治好咳嗽,后来上大学谈恋爱之后居然不治而愈了,真是不可思议。 ↩︎ 后来和家人去这家餐厅吃龙虾,这次吃的龙虾反而不好吃,有苦味。 ↩︎ 我不喜欢群发祝福语,每年最多给几位亲朋好友发自己写的祝福,诗婷就是其中一位。 ↩︎

2021/1/31
articleCard.readMore

用 Python 计算水电费

前段时间搬家了,在之前住的小区还有些费用没缴,包括水电费、物业费和公摊费。一开始用计算器和笔算,好几次算错。每次出错都要从头到尾算一遍,算得我很烦躁。我突然灵机一动,为什么不用 Python 算这笔麻烦帐呢?于是我就在 R Markdown 里用 Python 算帐了。把数字都放到变量里,搞错了就改某个变量的值,然后计算机就会计算出正确的结果,很快就算好了。计算机果然很擅长做这种琐碎的计算。 注意,以下代码用到的 f'{expr=}' 是 Python 3.8 引入的语法。另外,在 blogdown 里运行代码最好用 .Rmarkdown 而不是 .Rmd。用 .Rmd 之后目录显示不正常,用 .Rmarkdown 就没问题1。 # 1 2 import sys print(sys.version) 1 2 ## 3.8.6 (default, Jan 27 2021, 15:42:20) ## [GCC 10.2.0] # 1 2 3 4 5 6 公摊费单价 = 20 公摊费已出帐 = 190.72 公摊费未出帐 = 20 * 6 # 最近 6 个月的公摊费都未出帐,只好按照平均价格计算了。 公摊费总价 = 公摊费已出帐 + 公摊费未出帐 print(f"{公摊费总价=}") 1 ## 公摊费总价=310.72 # 1 2 3 4 物业费单价 = 125.7 物业费月份 = 2 物业费总价 = 物业费单价 * 物业费月份 print(f"{物业费总价=}") 1 ## 物业费总价=251.4 # 1 2 3 4 5 水费单价 = 4.75 水费起数 = 90 水费止数 = 103 水费总价 = (水费止数 - 水费起数) * 水费单价 print(f"水费总价:{水费总价}") 1 ## 水费总价:61.75 # 1 2 3 4 5 电费单价 = 0.65 电费起数 = 2474 电费止数 = 2569 电费总价 = (电费止数 - 电费起数) * 电费单价 print(f"{电费总价=}") 1 ## 电费总价=61.75 # 1 2 总价 = 物业费总价 + 水费总价 + 电费总价 + 公摊费总价 print(f"{总价=}") 1 ## 总价=685.62 r markdown - How to make floating table of contents work using the loveit theme with blogdown - Stack Overflow ↩︎

2021/1/29
articleCard.readMore

完全删除 Git 仓库的文件

步骤 # 完全删除 Git 仓库的文件是我不常用的操作,但好像每年都得用几次。还是把方法摘抄于此作为备忘录,省得下次再去搜索。这个方法是从 GitHub 文档抄来的,操作比较危险,请先把本文看完再尝试。可以把整个仓库复制到另一个地方来尝试前 2 步。 重写历史 1 2 3 git filter-branch --force --index-filter \ "git rm --cached --ignore-unmatch path/to/your/file" \ --prune-empty --tag-name-filter cat -- --all 注意,此命令需要在仓库根目录运行。如果反悔了就用 git reflog 查看第 2 条历史的哈希值,然后用 git reset --hard commit-id 就可以恢复了。 清除 reflog 1 2 3 git for-each-ref --format="delete %(refname)" refs/original | git update-ref --stdin git reflog expire --expire=now --all git gc --prune=now 执行了这些命令之后文件就真的消失了,无法恢复。 推送更改到远程仓库 1 2 git push origin --force --all git push origin --force --tags 联系 GitHub 删除 pull requests 中的文件 上述操作十分危险,如非必要,千万别在公开的仓库使用,不然会给开发者带来麻烦。使用后 Git 历史会被重写,别人 git pull 时会出错。 # 下面这几条技巧可以帮你避免添加不必要的文件。 用 .gitignore 排除文件 使用 GUI 软件,用 GUI 更容易看出具体的文件变动 使用 git add filename 和 git rm filename 来代替 git add . 和 git commit -a 使用 git add --interactive 添加文件 使用 git diff --cached 查看变动

2021/1/25
articleCard.readMore

大学抢课技巧

让大学生感到惊心动魄的事情,除了期末考试,可能还有抢选修课。如果没能抢到心仪的课,就只能捡漏了,不管愿不愿意,都得上一个学期的课。作为抢课界的博尔特,我就来分享一下我的抢课技巧。 使用更快的网络 可以用 Speedtest 测试网速。如果要和舍友挤着用校园网的话,可以试试手机热点。 给电脑插电,并关闭睡眠功能 提前 1 小时登陆教务系统 抢课前几分钟才登陆就可能就登陆不上了 打开几个浏览器的无痕浏览窗口登陆教务系统 只要内存够,能开几个窗口就开几个,窗口越多,机会越大。 排列好窗口,留一个窗口看北京时间 到时间后点击所有窗口的选课按钮 不要刷新,慢慢等待

2021/1/10
articleCard.readMore

沸水除臭法

前段时间家里突然有股恶臭,闻起来像是动物尸体的味道,闻到都想吐。有时能闻到,有时又闻不到,甚是烦恼。在家转了好几圈都没发现臭味的源头,太气了。把垃圾都打包放到门外,没用。打开门窗通风,也没用。最后发现洗手盆过滤网上有些剩菜,低头闻一闻,果然是这里。终于破案了,赶紧把剩菜倒掉。结果事情并没有那么简单,把剩菜倒掉之后洗手盆水管那里还是很臭。 在网上搜索一番,找到了一个除臭办法: 准备材料 小苏打粉 盐 白醋 沸水 混合盐和小苏打粉 倒到排水孔 倒入白醋 倒入沸水 小苏打粉和白醋混合之后会发生化学反应,产生白沫,发出滋滋滋的声音。感觉很神奇很好玩,又弄了几次,结果把半包小苏打粉和半瓶醋都用完了。终于没有臭味了。从此以后,我每次洗完碗都会把洗手盆的过滤网清理干净,再也不敢把剩菜留在那里了。 后记 只用小苏打粉和白醋就能产生化学反应,不用加盐也行。看到益辉说是热水才是除臭的根本,热水融化了硬油脂。益辉的评论让我开始怀疑自己之前的认知。于是在网上考究了一番,发现了好几个不同观点。刚刚又看到列弛说热水杀死了产生臭味的细菌。总结一下: 二氧化碳疏通管道(馒头汤) 碳酸氢钠和醋酸反应,产生二氧化碳,利用二氧化碳的气流和气压,疏通管道。 小苏打混白醋的产物没有清洁作用(科普中国) 小苏打混白醋产生的二氧化碳和乙酸钠是不具备任何清洁能力的。但如果把二者分开使用,其实都有一定清洁作用。小苏打可用于去油污,白醋可用于去水垢。 热水融化了引起臭味的硬油脂(谢益辉) 我猜测这三样材料里面真正除臭的是开水,我不太明白酸碱中和的化学反应在这里面有什么用(只会产生二氧化碳和醋酸钠的盐),我感觉单纯的开水加碱或者开水加酸应该都是可以的。如果你的洗碗池用了滤网,那么下水道堵的原因可能是动物油脂的积累。我以前把水槽下的水管子拆开看过,里面有很多硬油脂。用开水烫化了就通了。 热水杀死了产生臭味的细菌(张列弛) 请循其本。食物残渣为什么会臭?是因为产生了不好闻的气体。为什么会产生不好闻的气体?是因为有些成分被分解,产生了对鼻子来说不友好的物质。为什么会那些成分会被分解?是因为残渣里滋生了大量微生物。所以,除臭务尽,重在杀菌。没有什么菌是一盆热水不能解决的,如果有,那就两盆。 那到底什么物质才有除臭作用呢?「二氧化碳疏通管道」的说法比较牵强,就那一点点气体,产生的气压估计不能疏通管道,也许搋子产生的气压更大。「小苏打混白醋的产物没有清洁作用」的说法由化学副教授进行科学性把关,可信。那现在可以排除掉小苏打混白醋了。既然小苏打混白醋之后就没用了,那产生作用的就只有热水了。我觉得列驰从源头思考的方法很合理,可以解释为什么热水可以除臭。 按照解决问题源头的思路,最好还是不要让食物残渣流入下水管。没有堆积的食物残渣,也就不会滋生大量微生物了。厨房洗手盆自带的过滤网的孔比较大,于是我买了个不锈钢水槽过滤网叠在上面。这个的过滤网的孔比较小,更容易过滤掉食物残渣。在网购平台搜索「水槽过滤网」就可以买到了,有不锈钢的和一次性的。

2021/1/10
articleCard.readMore

blog 的词源

Jorn Barger 在 1997 年 12 月发明了 weblog 这个词,weblog 由 web 和 log 组成,指的是用于写日记的个人网站。Peter Merholz 这人比较特别,把 weblog 念成 we blog,简称 blog,然后这个缩略词就流传下来了。blog 除了作名词,亦可做动词,意为写网络日志。而写网络日志的人则称为 blogger。blog 有以下译名: 地区 译名 中国大陆 博客 台湾 部落格、网志 港澳 网志 马新 部落格、网志 blog 本来以文本为主体,但也有以其他内容为主体的 blog。以图片为主体的 blog 叫作 plog(photo blog),例如微信朋友圈。视频形式的 blog 叫作 vlog(video blog),例如【冰冰vlog.001】带大家看看每个冬天我必去的地方。内容字数有限的 blog 叫作 microblog(一条 Twitter 推文只能输入 280 个英文字母或者 140 个中文字),例如 Twitter、Facebook 和新浪微博。现在我来考考你,音频形式的 blog 叫什么呢?提示一下,音频的英文是 audio。揭示答案之前,先来学习一下各种 blog 的念法吧。 正确发音: 名称 发音 blog /blɒɡ/ plog /plɒɡ/ vlog /vlɒɡ/ 错误发音: 名称 发音 blog /biːlɒɡ/ plog /piːlɒɡ/ vlog /viːlɒɡ/、/vəlɒɡ/ 现在来揭晓答案啦,音频形式的 blog 叫作 alog(audio blog),才怪!其实音频形式的 blog 叫作 podcast,中文译名是播客,例如故事 FM 和 Steve 说。podcast 的发音是:/英式 ˈpɒdkɑːst; 美式 ˈpɑːdkæst/。 参考文献: 博客 - 维基百科,自由的百科全书

2021/1/1
articleCard.readMore

订阅

欢迎使用 RSS 阅读器1订阅更新,本站的 RSS 链接是 https://cyrusyip.org/zh-cn/index.xml。有时候我会更新旧文,推荐你在阅读器点击文章链接,跳转到本站阅读最新版本。 我目前使用 Inoreader。 ↩︎

2020/12/29
articleCard.readMore

关于

自我介绍 # 我叫叶寻,英文名是 Cyrus Yip。相信自学的力量,觉得为满足好奇心而学习是件十分幸福的事。本站就是通过自学搭建起来的。 # 平时喜欢看书、写作、玩单机游戏(2020 年前)、看日本动画、编程、学习一切感兴趣的事物。 对我生活影响最大的书是《正念》和《正念療癒力》。从 2018 年开始每天做半小时正念冥想。现在仍在践行正念,努力地活在当下和给生活做减法。 为什么要活在当下呢?因为活在过去容易抑郁,活在未来容易焦虑,所以还是活在当下最好。没办法穿越到过去或未来,当下是唯一能活着的时间。但是人脑常常做时空旅行,跳到过去或未来,所以还要继续修行呢。学习正念后对禅宗和佛教感兴趣,不过只读过圣严法师的学佛三书。尝试读佛经,但是文言文太难读懂了,于是就放弃了,希望有一天能继续。 我总有好多想做的事情。尝试过时间管理方法来提高做事效率,把时间表排满。常常没办法做完待办列表的事,然后很自责。虽然做的事看起来多,但是每件都不深入,看着未完成的代办列表也焦虑。最后意识到每天精力和时间都有限,就放弃时间管理了,目前只专注于几件事。目前每天专注做两三件事感觉很满足。 最让我震撼的游戏是时空轮回(Ever17),剧情优秀,悬念设计极佳。这个游戏剧透就不精彩了,也不知道怎么推荐了。因为时空轮回采用了视觉小说特有的叙事方式(存档读档、多分支剧情、多结局),所以没办法改编成动画,名气只停留在视觉小说的圈子了,真的很可惜。 八方旅人是我第一个打通的英文游戏(我玩的时候还没中文),玩了一百个小时。精致的像素风画面很对我胃口,毕竟我是玩红白机游戏长大的。游戏音乐也很好听。打通游戏之后感觉之前努力学英语真好啊,玩游戏都不用等中文版了,对自己的英语水平也更有信心了。 # My Blog Arch Linux Forum ArchWiki Disqus GitHub Hugo forum Mastodon Matrix (请勿加好友或者私信) NixOS Discourse Proxmox Support Forum Reddit Stack Overflow Twitter Arch Linux 中文社区 小众软件官方论坛 统计之都 # 鼓励. # 这里其实不是常见问题栏目,毕竟没几个人问我问题。用「常见问题」纯粹因为本文的一级标题(其实是二级)都是四个字的,不继续用一样的字数让我很不爽。 # 实不相瞒,被我埋进棺材的文章诈尸了。好吧,这样说你肯定不信。其实是我家网速太慢了,花了两个月才上传文章。这听起来更离谱了,是吧。真实原因是我写文章不一定一天能写完,写完一般也不会马上发,会检查几遍,修改好再发。 # 本站不交换友情链接,以下是单向友情链接,按拼音排序。 谢益辉:生活、R 语言、他开发的 R 软件包让写作变得更简单、统计之都创始人、本站早期读者 袁凡:阿木狗主、小说、本站早期读者 张列弛:文学、生物、本站早期读者 # 本站文章的许可证是署名-非商业性使用-相同方式共享 4.0 国际(CC BY-NC-SA 4.0),欢迎转载,可在原文基础上修改。转载时请在显著位置标注原标题、原文链接、作者、作者博客链接、是否修改原文、许可证,且不能用于商业目的(盈利)。链接可用超链接或纯文本的形式。许可证必须保持一致,可用中文「署名-非商业性使用-相同方式共享 4.0 国际」,或英文「CC BY-NC-SA 4.0」。 转载示例: 原标题:为什么要接纳自己 原文链接:https://cyrusyip.org/zh-cn/post/2021/05/14/why-accept-myself/ 作者:叶寻 作者博客:https://cyrusyip.org/ 是否修改:否 许可证:署名-非商业性使用-相同方式共享 4.0 国际 本文原标题为「为什么要接纳自己」,作者为「叶寻」,许可证为 CC BY-NC-SA 4.0,文章有改动。 # 如果文章内容有误,可以 直接留言 在代码库提交合并请求 点击这里 输入文章网址的最后一部分,比如 live-for-myself 点击文件 点击铅笔图标 编辑 提交 如果网站有问题,请在代码库反馈。如果不方便的话,在本页评论也行。 # 本站采用以下工具搭建: 构建:Hugo 主题:hugo-theme-yue(我自己开发的,嘻嘻) 代码托管:GitHub(本站的源代码) 部署:Cloudflare Pages 评论服务:Disqus、giscus 域名注册:Cloudflare Registrar

2020/12/29
articleCard.readMore

做笔译需要什么能力

疫情刚爆发的时候在家上学,比较清闲,就在网上尝试兼职笔译。在网上搜了一圈笔译网站,感觉有道人工翻译和我译网还可以。有道人工翻译需要投简历,我没什么可写懒得写就去试试我译网了。注册了帐号之后,不能直接接单,得通过测试才行。参加考试这个事也是六七个月之前了,有些细节可能记得不太清楚。 选择考试题目 先选择语言,再选择领域。选择领域领域的时候一下就蒙了,在学校做的翻译练习几乎都是文学作品翻译。作为英语专业学生,真的是除了英语,啥都不会 ε(´סּ︵סּ`)з。 第一次选择了 App 领域,我猜应该是翻译手机应用的界面吧。结果一做题目,完全不是我猜那个意思,总之都是我看不懂的东西。每月只有一次考试机会,我又注册多一个帐号再试一次,这次选了游戏领域(英译中)。题目是 8 道判断对错题和 2 道翻译题,考试时常为 30 分钟,每月只能考一次。 判断题例子 1 判断题例子 2 翻译题例子 1 电子游戏的内容还能理解,但是扑克牌的知识我完全不懂,没辙了。翻译的时候还遇到一个问题:有些英语概念我能理解其涵义,但是却不会用中文表达,或者用很长的中文才能表达原意。我猜这是因为我经常用英英词典,导致有些英文概念我只能用英文解释。总结一下,做笔译除了要懂外语,还要有扎实的母语功底、双语转换能力、了解特定行业的知识。 中文功底不扎实,译出来的中文会很长。双语转换能力差可能会导致想不到简洁的表达。拿「bossy」这个词来举例子,它的英文意思是「always telling other people what to do, in a way that is annoying」1,要是我来翻译只能会直接就说「总爱告诉别人怎么做」。但词典的中文解释为「爱发号施令的,专横的」,比我的简洁多了。我知道中文的「发号施令」和「专横」,但是就是想不到可以用这两个词。双语转换能力差还会导致一个毛病:不必要的中英混杂2。有些概念可以用中文表达,为什么讲中文的时候非要用英文单词呢?比如「你用什么翻译 App3」可以说成「你用什么翻译软件/应用」。比如「我收到了微软的 offer」可以说成「我被微软录取了」。不了解行业知识就会没法翻译,让一个不懂法的人去翻译合同,那肯定是要闹笑话的。 学外语这个问题很好解决,市面上有很多学习教程了,选一个开始学就行。免费的和收费的都有。我自学英文是从看《把你的英语用起来!》开始的,这本书从学音标开始讲英语自学法,十分适合零基础的同学。虽然方法很多,但是比选学习方法更重要的是要真的去学习。了解行业知识也不难解决,学习英文和中文的资料就行。如果想做金融方面的笔译,那就读中文的金融教材和英文的金融教材。想翻译游戏,就玩同一个游戏的英文版和中文版。剩下的提升中文功底和双语转换能力我就不太了解了。 延伸阅读: 变态中文 - Yihui Xie | 谢益辉 中英混杂语之十恶之首:动词 work - Yihui Xie | 谢益辉 江阔云低断雁叫西风 - Yihui Xie | 谢益辉 欧化中文 - 维基百科,自由的百科全书 连淑能, 2010. 英汉对比研究[M]. 高等教育出版社. bossy 的解释出自朗文当代高级英语辞典(英英.英汉双解)(第五版) ↩︎ 我不是反对所有中英混杂,提及专业术语时用英文没什么关系,但是日常用语完全没必要用英文,用多了中文都退化了。另外,说话满口英文,不见得别人都能听懂。 ↩︎ app 是 application 的缩写,应该念 /æp/而不是念 A-P-P 这三个字母。不过说 A-P-P 很多,A-P-P 已经变成「正确」读法了。/æp/ 是 1 个音节,应用/软件是 2 个音节,A-P-P 是 3 个音节。用 A-P-P 既错误又繁琐(多动一两下嘴巴)。 ↩︎

2020/12/29
articleCard.readMore

命令行实例

本文用于收集我记不住的实用的命令行用法。 # 1 2 3 # 启动已停止的容器 docker start f357e2faab77 # restart it in the background docker attach f357e2faab77 # reattach the terminal & stdin docker - I lose my data when the container exits - Stack Overflow # 1 2 3 4 5 # 下载视频 you-get https://www.iqiyi.com/v_m72044yl88.html yt-dlp https://www.youtube.com/watch\?v\=9gfECJHQElo # 下载 Youtube 歌单(最佳质量、附上序号) yt-dlp --output '%(playlist_index)s-%(title)s.%(ext)s' -f 'bestaudio' 'https://www.youtube.com/watch?v=T4SimnaiktU&list=PLfAuqOtSFlrAwfk6j3PlSXhssBXzcXREw' # 1 2 # 把当前文件夹的所有 .webm 文件转换为 .mp3 for i in *.webm; do ffmpeg -i "$i" "${i%.*}.mp3"; done # 1 you-get -p vlc https://www.iqiyi.com/v_m72044yl88.html # 先安装 ImageMagick: 1 sudo apt install imagemagick 把 jpg 图片转换为 png 图片: 1 convert input.jpg output.png # SoX 和 Mp3Wrap 都可以用来合成 MP3。他们的区别如下(测试文件大小为 3.7 MB 和 4.4 MB)1: SoX Mp3Wrap 速度 10.5 秒 瞬间 还原文件 否 是 正常播放(Elisa、VLC、mpv) 是 只有 mpv 可以正常播放,其他播放器播放听起来不太对劲 输出文件/源文件 97.7% 100.006% # 安装 SoX: 1 sudo apt-get install sox libsox-fmt-mp3 把 input-1.mp3 和 input-2.mp3 合成为 output.mp3: 1 sox input-1.mp3 input-2.mp3 output.mp3 注意,要按顺序输入待合成的 MP3,把输出文件写在最后。 # 安装: 1 sudo apt install mp3wrap mp3splt 把 input-1.mp3 和 input-2.mp3 合成为 output.mp3: 1 mp3wrap output.mp3 input-1.mp3 input-2.mp3 注意,这次是先写输出文件,再写输入文件。输出的文件会加上后缀 MP3WRAP,所以生成的输出文件名为 output_MP3WRAP.mp3。这个后缀用于提醒用户文件是 Mp3Wrap 生成的,可以用 Mp3splt 还原: 1 2 mp3splt -w output_MP3WRAP.mp3 # -w Warp Mode,用于拆分由 Mp3Wrap 和 AlbumWrap 生成的文件 上述命令会把 output_MP3WRAP.mp3 还原成原来的 input-1.mp3 和 input-2.mp3(不会删除 output_MP3WRAP.mp3)。还原出来的文件和原文件是一模一样的。 # 把 MP3 拆分多个文件,每份 30 秒: 1 ffmpeg -i input.mp3 -f segment -segment_time 30 -c copy out%03d.mp3 # 剪取 input.mp4 06:01.511 至 06:23.841 的内容,并保存为 output.mp4: 1 ffmpeg -ss 06:01.511 -to 06:23.841 -i input.mp4 -c copy output.mp4 选项含义: -ss (set the start time)指定视频开始时间 -to 指定结束时间 -i (input)指定输入文件 -c copy 表示使用相同编码方式(速度更快) output.mp4 是输出文件名 这些选项一定要按照顺序写,不然剪出来的视频时间不对。 我试过把 -i 先写在前面,也就是这样: 1 ffmpeg -i input.mp4 -ss 06:01.511 -to 06:23.841 -c copy output.mp4 结果输出视频开头的时间总是不对,然后整了两小时都不知道咋回事。遇到 ffmpeg 以前,我都不知道命令行软件的选项位置会影响结果。啊!多么痛的领悟!如果把 -c copy 选项也去掉的话,输出视频又正确了,真是搞不懂啊。 1 ffmpeg -i input.mp4 -ss 06:01.511 -to 06:23.841 output.mp4 # 在 1080P 的视频底部加上 100 像素高的黑色长方形遮罩。文档:https://ffmpeg.org/ffmpeg-filters.html#drawbox。 1 ffmpeg -i input.mp4 -vf "drawbox=x=0:y=(ih-100):w=iw:h=100:color=black:t=fill" output.mp4 # 如果直接用 echo $PATH 查看 PATH 变量,结果很难看,很难分清楚哪个目录是哪个。 1 2 $ echo $PATH /home/user/bin:/home/user/.local/bin:/home/user/bin:/home/user/.local/bin:/home/user/bin:/home/user/.local/bin:/home/user/bin:/home/user/.local/bin:/home/user/miniconda3/condabin:/home/user/bin:/home/user/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin 用 tr ':' '\n' <<< "$PATH",结果一目了然。<<< 把右边的 $PATH 传递到左边,tr ':' '\n' 把 $PATH 中的 : 转换为换行符。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 $ tr ':' '\n' <<< "$PATH" /home/user/bin /home/user/.local/bin /home/user/bin /home/user/.local/bin /home/user/bin /home/user/.local/bin /home/user/bin /home/user/.local/bin /home/user/miniconda3/condabin /home/user/bin /home/user/.local/bin /usr/local/sbin /usr/local/bin /usr/sbin /usr/bin /sbin /bin /usr/games /usr/local/games /snap/bin 参考:shell - Show PATH in a human-readable way - Unix & Linux Stack Exchange # 1 2 3 4 # 重启 Plasma kquitapp5 plasmashell; sleep 2; kstart5 plasmashell # 重新加载软件列表 kbuildsycoca5 参考:kwin - Can I restart the KDE Plasma Desktop without logging out? - Ask Ubuntu # 1 echo "40 70" | sudo tee /sys/devices/platform/huawei-wmi/charge_control_thresholds 测试文件为紅蓮華(input-1.mp3,3.7 MB)和 from the edge (input-2.mp3,4.4 MB),播放器为 Elisa、VLC、mpv。 ↩︎

2020/12/25
articleCard.readMore

用 BASH 脚本更新各类软件包

刚用 Ubuntu 的时候,觉得用 apt 安装软件很方便,从此不再需要像用 Windows 一样要去官方下载软件。用久了也发现 Ubuntu 软件仓库有两个问题:软件不是最新版本、缺少某些软件。要解决这些问题,除了添加 PPA 以外,就只能用的其他包管理器作为补充。用多了包管理器,每次更新都要输入好几个命令,太麻烦啦。还是用 BASH 脚本一次性更新各类软件包吧。 先安装待会需要用的软件,apt-fast 用于加速 apt 的下载速度,pipupgrade 用来更新 Python 包,npm-check 用于更新 npm 包。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 # install apt-fast # homepage: https://github.com/ilikenwf/apt-fast sudo add-apt-repository ppa:apt-fast/stable sudo apt-get update sudo apt install apt-fast # install pipupgrade # homepage: https://github.com/achillesrasquinha/pipupgrade pip install pipupgrade # install npm-check # homepage: https://github.com/dylang/npm-check sudo npm install -g npm-check 下面就是更新脚本,将它保存到 PATH 变量包含的目录里,然后授予执行权限就可以直接在命令行运行了。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 #!/bin/bash -x # apt sudo apt update sudo apt-fast upgrade -y # tlmgr sudo tlmgr update --self --all # npm sudo npm-check --global --update--all # pip pipupgrade --ignore-error -y # cran Rscript -e "update.packages()"

2020/12/25
articleCard.readMore

不指定路径运行自己写的软件

在 Linux 上运行自己写的软件必须指定路径才能运行。举个例子,我写了个 BASH 脚本,把代码保存到 hello_world 文件,放到 ~/Desktop,并赋予它运行权限。 1 2 #!/bin/bash echo "Hello, World!" 如果我们在终端执行 hello_world 会怎么样呢? 1 2 3 4 $ hello_world Command 'hello_world' not found, did you mean: command 'hello-world' from snap hello-world (6.4) See 'snap info <snapname>' for additional versions. 完全不行啊。必须在终端输入 ~/Desktop/hello_world 才能运行 hello_world。 1 2 $ ~/Desktop/hello_world Hello, World! 怎么样才能像 mv 一样可以不输入路径就运行呢?要回答这个问题就得先弄清楚为什么 BASH 可以直接执行 mv。原因就是 PATH 变量,它保存了可执行文件的目录。输入 tr ':' '\n' <<< "$PATH" 可以查看 PATH 变量。 1 2 3 4 5 6 7 8 9 10 11 12 13 tr ':' '\n' <<< "$PATH" /home/user/miniconda3/condabin /home/user/bin /home/user/.local/bin /usr/local/sbin /usr/local/bin /usr/sbin /usr/bin /sbin /bin /usr/games /usr/local/games /snap/bin 当你不指定路径,直接输入一个命令(例如 mv)时,BASH 会从上面的目录中查找是否有这个程序,有就运行,没有就显示 command not found。所以把我们前面写的 hello_world 放入其中一个目录就可以运行了。 1 2 3 $ mv ~/Desktop/hello_world /home/user/.local/bin $ hello_world Hello, World! 随便找个目录丢进去也不太好,要删除文件的时候不小心删除了系统自带的软件就糟糕了。最好自己建立一个目录专门储存自己写的软件,一般 ~/bin 用于储存用户自己的软件。那我们可以把自己写的软件存到 ~/bin。设置步骤: 建立目录 1 mkdir ~/bin 把目录添加到 PATH 变量 把 export PATH="/home/hunter/bin:$PATH" 添加到 ~/.bashrc1(如果用 zsh 就添加到 ~/.zshrc) 打开新的终端窗口 现在把软件放到 ~/bin 之后直接在终端输入就可以运行了。 延伸阅读: Writing shell scripts - Lesson 1: Writing your first script and getting it to work PATH (变量) - 维基百科,自由的百科全书 bash - What is the purpose of .bashrc and how does it work? - Unix & Linux Stack Exchange .bashrc 用于初始化 BASH,每次打开 BASH,BASH 都会运行 .bashrc。 ↩︎

2020/12/24
articleCard.readMore

键盘使用技巧

以前用 Windows 的时候用鼠标比较多,一直忽略键盘右边的按键。转到 Linux 之后才发现被我忽略的按键是多么好用。 # 了解按键的全称有利于记忆按键的功能。 缩写 全称 符号 Tab Tabulator / Tabular ↹ Alt Alternate Ctrl Control Del Delete Shift ⇧ Backspace ← Enter ↵ PgUp PageUp PgDn PageDown Ins Insert PrtSc Print Screen # Backspace 用于删除光标左边的 1 个字符,Delete 用于删除光标右边的 1 个字符。 # Tab 用于缩进内容,Shift Tab 用于取消缩进。 # PageUp 用于将光标或页面前移 1 个屏幕的大小,PageDown 用于讲光标或页面后移 1 个屏幕的大小。Home 在编辑器中的作用是把光标移动到行首,在阅读器中的作用是把页面移动到文档开头。End 在编辑器的作用是把光标移动到行尾,在阅读器中的作用是把页面移动到文档结尾。 # Ctrl ← 用于把光标左移 1 个单词的长度,Ctrl → 用于把光标右移 1 个单词的长度。Ctrl Backspace 用于删除光标左边的 1 个单词,Ctrl Delete 用于删除光标右边的 1 个单词。 # Shift + 移动光标的按键用于选中字符。Shift ←/→ 用于选中 1 个字符,按住 Shift,再按多几次 ←/→ 可以选中多个字符。Shift ↑/↓ 用于选中长度为 1 行的内容。Shift Home/End 用于选中光标至行首或行尾的内容。Shift PageUp/PageDown 用于选中 1 个页面的内容。 # Insert 用于切换文本输入模式。文本输入有两种,一是覆盖模式,在此模式下新输入的字符会代替光标处的字符;另一个模式是插入模式,在此模式下新输入的字符会插入到光标处,原本在光标后的字符后移。 PrtSc 全称是 Print Screen。在 KDE Plasma 中,PrtSc 用于调用 Spectacle 来截图。在 Windows 中,按下 PrtSc 之后系统会把全屏截图保存到剪切板,在编辑器(如 MS Office)中按下 Ctrl V 就可以粘贴截图。按下 Alt PrtSc 则会截取当前窗口。 # Computer keyboard - Wikipedia

2020/12/21
articleCard.readMore

Markdown 技巧

使用 R Markdown # 常用的 GitHub Flavored Markdown 功能很少,熟悉之后可以使用更强大的 R Markdown。 R Markdown 的优势: 多用途 R Markdown 可以用来写文档,输出格式为 PDF、HTML、Word 等,写书可以用 bookdown。除了写文档,R Markdown 还可以用来写幻灯片(ioslides、Slidy、Beamer、Powerpoint、xaringan 等)和写博客(blogdown)。 可运行代码 R Markdown 中可以插入代码,编译文档后代码结果会在输出文档里面。这样的话,改了代码新的结果也会自动插入到输出文档,就不用自己手动插入图片了。 # 下面的有序列表显示效果一样 1 2 3 1. 香蕉 2. 葡萄 3. 菠萝 1 2 3 1. 香蕉 1. 葡萄 1. 菠萝 1 2 3 1. 香蕉 111. 葡萄 10. 菠萝 它们都会显示为 香蕉 葡萄 菠萝 另外,列表数字可以不以 1 为开头。比如 1 2 3 2. 香蕉 2. 葡萄 2. 菠萝 会显示为 香蕉 葡萄 菠萝 在有序列表中使用同一个数字有两个好处:一是不需要自己手动编号、二是使用 Git 管理文件时变动更少。 # 超链接的语法是[链接文本](链接网址),图片的语法是![图片标题](图片网址)。把图片当成超链接的文本,放到超链接的语句中就可以生成带有超链接的图片,也就是[![图片标题](图片网址)](链接网址)。 这是 GitHub 的吉祥物 Octocat ![octocat](https://octodex.github.com/images/kimonotocat.png) 这是 Github 的链接 [GitHub](https://github.com/) 把它们拼凑起来就可以制作带有 GitHub 链接的 Octocat [![octocat](https://octodex.github.com/images/kimonotocat.png)](https://github.com/) 如果点击上面的图片不会跳转到 GitHub,可能是因为本站使用了 PhotoSwipe 这样的相册插件。你可以把代码复制到 Markdown 编辑器试试看。 # 如果代码块里包含 N 个 `,在需要代码块前后使用 N+1 个 ` 把它包裹起来,不然就会显示错误。下面内容会显示为两个空代码块夹着 print("Hello, World!")。 1 2 3 4 5 ``` ``` print("Hello, World!") ``` ``` 上面代码的正确写法应该是 1 2 3 4 5 ```` ``` print("Hello, World!") ``` ```` 它会显示为 1 2 3 ``` print("Hello, World!") ``` # 用空行隔开不同元素可以消除歧义,避免错误的显示效果。如果不用空行的话,可能会出现意料之外的显示效果。如果我用下面的写法列举我喜欢吃的食物,猜猜 Markdown 编辑器会如何显示。 1 2 3 4 5 6 7 8 水果: 1. 椰子 2. 香蕉 3. 菠萝 烧腊: 1. 叉烧 2. 烧鸭 3. 白切鸡 点击这里查看不同解析器的结果,有三种显示效果。 现在你应该知道不加空行的严重后果了。我们再来看看那个错误示范。 1 2 3 4 5 6 7 8 水果: 1. 椰子 2. 香蕉 3. 菠萝 烧腊: 1. 叉烧 2. 烧鸭 3. 白切鸡 它应该包含了 4 个元素:依次为段落、有序列表、段落、有序列表。在元素间加上空行显示就没问题了。点击这里查看效果,这次所有解析结果都正常。 1 2 3 4 5 6 7 8 9 10 11 水果: 1. 椰子 2. 香蕉 3. 菠萝 烧腊: 1. 叉烧 2. 烧鸭 3. 白切鸡 # 给 Typora 文章、目录和大纲的标题编号: 按下 Ctrl + ,打开 Typora 设置 点击 Appearance -> Open Theme Folder来打开主题文件夹 Linux 的路径为 ~/.config/Typora/themes Windows 的路径为 %APPDATA%\Typora\themes 新建一个名为 base.user.css 的文件,把下面的代码粘贴进去(出处) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 /************************************** * Header Counters in Article **************************************/ /** initialize css counter */ #write { counter-reset: h1 } h1 { counter-reset: h2 } h2 { counter-reset: h3 } h3 { counter-reset: h4 } h4 { counter-reset: h5 } h5 { counter-reset: h6 } /** put counter result into headings */ #write h1:before { counter-increment: h1; content: counter(h1) ". " } #write h2:before { counter-increment: h2; content: counter(h1) "." counter(h2) ". " } #write h3:before, h3.md-focus.md-heading:before /** override the default style for focused headings */ { counter-increment: h3; content: counter(h1) "." counter(h2) "." counter(h3) ". " } #write h4:before, h4.md-focus.md-heading:before { counter-increment: h4; content: counter(h1) "." counter(h2) "." counter(h3) "." counter(h4) ". " } #write h5:before, h5.md-focus.md-heading:before { counter-increment: h5; content: counter(h1) "." counter(h2) "." counter(h3) "." counter(h4) "." counter(h5) ". " } #write h6:before, h6.md-focus.md-heading:before { counter-increment: h6; content: counter(h1) "." counter(h2) "." counter(h3) "." counter(h4) "." counter(h5) "." counter(h6) ". " } /** override the default style for focused headings */ #write>h3.md-focus:before, #write>h4.md-focus:before, #write>h5.md-focus:before, #write>h6.md-focus:before, h3.md-focus:before, h4.md-focus:before, h5.md-focus:before, h6.md-focus:before { color: inherit; border: inherit; border-radius: inherit; position: inherit; left:initial; float: none; top:initial; font-size: inherit; padding-left: inherit; padding-right: inherit; vertical-align: inherit; font-weight: inherit; line-height: inherit; } /************************************** * Header Counters in TOC **************************************/ /* No link underlines in TOC */ .md-toc-inner { text-decoration: none; } .md-toc-content { counter-reset: h1toc } .md-toc-h1 { margin-left: 0; font-size: 1.5rem; counter-reset: h2toc } .md-toc-h2 { font-size: 1.1rem; margin-left: 2rem; counter-reset: h3toc } .md-toc-h3 { margin-left: 3rem; font-size: .9rem; counter-reset: h4toc } .md-toc-h4 { margin-left: 4rem; font-size: .85rem; counter-reset: h5toc } .md-toc-h5 { margin-left: 5rem; font-size: .8rem; counter-reset: h6toc } .md-toc-h6 { margin-left: 6rem; font-size: .75rem; } .md-toc-h1:before { color: black; counter-increment: h1toc; content: counter(h1toc) ". " } .md-toc-h1 .md-toc-inner { margin-left: 0; } .md-toc-h2:before { color: black; counter-increment: h2toc; content: counter(h1toc) ". " counter(h2toc) ". " } .md-toc-h2 .md-toc-inner { margin-left: 0; } .md-toc-h3:before { color: black; counter-increment: h3toc; content: counter(h1toc) ". " counter(h2toc) ". " counter(h3toc) ". " } .md-toc-h3 .md-toc-inner { margin-left: 0; } .md-toc-h4:before { color: black; counter-increment: h4toc; content: counter(h1toc) ". " counter(h2toc) ". " counter(h3toc) ". " counter(h4toc) ". " } .md-toc-h4 .md-toc-inner { margin-left: 0; } .md-toc-h5:before { color: black; counter-increment: h5toc; content: counter(h1toc) ". " counter(h2toc) ". " counter(h3toc) ". " counter(h4toc) ". " counter(h5toc) ". " } .md-toc-h5 .md-toc-inner { margin-left: 0; } .md-toc-h6:before { color: black; counter-increment: h6toc; content: counter(h1toc) ". " counter(h2toc) ". " counter(h3toc) ". " counter(h4toc) ". " counter(h5toc) ". " counter(h6toc) ". " } .md-toc-h6 .md-toc-inner { margin-left: 0; } /************************************** * Header Counters in Content **************************************/ /** initialize css counter */ #write { counter-reset: h1 } h1 { counter-reset: h2 } h2 { counter-reset: h3 } h3 { counter-reset: h4 } h4 { counter-reset: h5 } h5 { counter-reset: h6 } /** put counter result into headings */ #write h1:before { counter-increment: h1; content: counter(h1) ". " } #write h2:before { counter-increment: h2; content: counter(h1) "." counter(h2) ". " } #write h3:before, h3.md-focus.md-heading:before { /*override the default style for focused headings */ counter-increment: h3; content: counter(h1) "." counter(h2) "." counter(h3) ". " } #write h4:before, h4.md-focus.md-heading:before { counter-increment: h4; content: counter(h1) "." counter(h2) "." counter(h3) "." counter(h4) ". " } #write h5:before, h5.md-focus.md-heading:before { counter-increment: h5; content: counter(h1) "." counter(h2) "." counter(h3) "." counter(h4) "." counter(h5) ". " } #write h6:before, h6.md-focus.md-heading:before { counter-increment: h6; content: counter(h1) "." counter(h2) "." counter(h3) "." counter(h4) "." counter(h5) "." counter(h6) ". " } /** override the default style for focused headings */ #write>h3.md-focus:before, #write>h4.md-focus:before, #write>h5.md-focus:before, #write>h6.md-focus:before, h3.md-focus:before, h4.md-focus:before, h5.md-focus:before, h6.md-focus:before { color: inherit; border: inherit; border-radius: inherit; position: inherit; left: initial; float: none; top: initial; font-size: inherit; padding-left: inherit; padding-right: inherit; vertical-align: inherit; font-weight: inherit; line-height: inherit; } /************************************** * Header Counters in Sidebar **************************************/ .sidebar-content { counter-reset: h1 } .outline-h1 { counter-reset: h2 } .outline-h2 { counter-reset: h3 } .outline-h3 { counter-reset: h4 } .outline-h4 { counter-reset: h5 } .outline-h5 { counter-reset: h6 } .outline-h1>.outline-item>.outline-label:before { counter-increment: h1; content: counter(h1) ". " } .outline-h2>.outline-item>.outline-label:before { counter-increment: h2; content: counter(h1) "." counter(h2) ". " } .outline-h3>.outline-item>.outline-label:before { counter-increment: h3; content: counter(h1) "." counter(h2) "." counter(h3) ". " } .outline-h4>.outline-item>.outline-label:before { counter-increment: h4; content: counter(h1) "." counter(h2) "." counter(h3) "." counter(h4) ". " } .outline-h5>.outline-item>.outline-label:before { counter-increment: h5; content: counter(h1) "." counter(h2) "." counter(h3) "." counter(h4) "." counter(h5) ". " } .outline-h6>.outline-item>.outline-label:before { counter-increment: h6; content: counter(h1) "." counter(h2) "." counter(h3) "." counter(h4) "." counter(h5) "." counter(h6) ". " } 保存文件并重启 Typora # Markdown 有两种标题写法,一种是 ATX 标题(ATX headings): 1 2 3 4 5 6 7 8 9 10 11 # foo ## foo ### foo #### foo ##### foo ###### foo 另一种是 Setext 标题(Setext Headings): 1 2 3 4 5 Title ===== Subhead ------- 有很长一段时间,我都没法区分哪种标题是 ATX,哪种是 Setext。我特地用词典查 ATX 和 Setext,根本查不到释义。最近在谷歌和维基百科的帮助下,才发现原来这两个标题写法不是 Markdown 原创的,是出自 atx(the true structured text format) 和 Setext (Structure Enhanced Text)。 # Markdown 的格式有限,要使用 Markdown 不支持格式,就只能混用其他标记语言。但是混用标记语言可能会让你陷入追求格式的泥潭。举个例子,Markdown 不支持右对齐,要对文字右对齐只能使用 HTML 代码,比如 <div style="text-align: right">右对齐的文字</div>。这么做有两个问题,一是要输入长长的代码,二是转换成 HTML 以外的文档(如 PDF)右对齐代码就失效了。下面这个 Markdown 文件转换成 PDF 的话,右对齐会失效。 1 2 3 4 5 > 春有百花秋有月,夏有凉风冬有雪。 > > 若无闲事挂心头,便是人间好时节。 > > <div style="text-align: right">——无门慧开</div> 春有百花秋有月,夏有凉风冬有雪。 若无闲事挂心头,便是人间好时节。 ——无门慧开 其实在 R Markdown 中有让右对齐代码同时对 HTML 与 PDF 生效的方法(参考资料:9.6 Custom blocks (*) | R Markdown Cookbook)。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 --- output: pdf_document: default html_document: default --- <style> .flushright { text-align: right; } </style> > If your mind isn’t clouded by unnecessary things, > > This is the best season of your life. > > ::: {.flushright data-latex=""} > --- Wu-Men > ::: # # 1 2 3 4 5 --- output: pdf_document: extra_dependencies: ["bbm", "threeparttable"] --- 1 2 3 4 5 6 7 8 --- output: pdf_document: extra_dependencies: caption: ["labelfont={bf}"] hyperref: ["unicode=true", "breaklinks=true"] lmodern: null --- # 1 2 3 4 5 6 --- header-includes: - \usepackage{bbm} output: pdf_document --- # 1 2 3 4 5 6 --- output: pdf_document: includes: in_header: mystyles.sty --- 1 2 3 4 5 % mystyles.sty \usepackage{bbm} \usepackage{threeparttable} \usepackage{booktabs} \usepackage{expex} # 6.4 Include additional LaTeX packages | R Markdown Cookbook knitr - How to include LaTeX package in R Markdown? - TeX - LaTeX Stack Exchange

2020/12/15
articleCard.readMore

trash-cli 中文手册

rm 是常用的 BASH 命令,但是误删文件后比较难恢复。用 trash-cli 更安全,它只是把文件移动到回收站,这样误删文件也很容易恢复。我觉得这个软件挺好用的,就把官方文档翻译成中文了。 # trash-cli 用于移动文件到回收站,同时会记录文件的原地址、删除日期和权限。trash-cli 和 KDE、GNOME、XFCE 使用同一个回收站,你可以在命令行或脚本运行 trash-cli。 trash-cli 提供以下命令: trash-put 把文件或目录移动到回收站 trash-empty 清空回收站 trash-list 列出回收站文件 trash-restore 恢复回收站文件 trash-rm 删除回收站文件 # 移动文件到回收站: $ trash-put 列出回收站文件: $ trash-list 2008-06-01 10:30:48 /home/andrea/bar 2008-06-02 21:50:41 /home/andrea/bar 2008-06-23 21:50:49 /home/andrea/foo 搜索回收站文件: $ trash-list | grep foo 2007-08-30 12:36:00 /home/andrea/foo 2007-08-30 12:39:41 /home/andrea/foo 恢复回收站文件: $ trash-restore 0 2007-08-30 12:36:00 /home/andrea/foo 1 2007-08-30 12:39:41 /home/andrea/bar 2 2007-08-30 12:39:41 /home/andrea/bar2 3 2007-08-30 12:39:41 /home/andrea/foo2 4 2007-08-30 12:39:41 /home/andrea/foo What file to restore [0..4]: 4 $ ls foo foo 删除所有回收站文件: $ trash-empty ago: $ trash-empty --> 删除回收站中 n 天前被回收的文件: $ trash-empty <days> 示例: $ date Tue Feb 19 20:26:52 CET 2008 $ trash-list 2008-02-19 20:11:34 /home/einar/today 2008-02-18 20:11:34 /home/einar/yesterday 2008-02-10 20:11:34 /home/einar/last_week $ trash-empty 7 $ trash-list 2008-02-19 20:11:34 /home/einar/today 2008-02-18 20:11:34 /home/einar/yesterday $ trash-empty 1 $ trash-list 2008-02-19 20:11:34 /home/einar/today 只删除符合某种模式的文件: $ trash-rm \*.o 注意:要用双引号圈住模式来避免 shell 拓展。 # 如何创建顶级 .Trash 目录? # 步骤: sudo mkdir --parent /.Trash sudo chmod a+rw /.Trash sudo chmod +t /.Trash rm 的别名设置为 trash-put 吗? # 可以,但不应该这样做。以前我觉得这是个好主意,但现在我不觉得。 虽然 trash-put 的界面看起来与 rm 兼容,但它们有不同的语法,这些差异会导致一些问题。比如,用 rm 删除目录时需要 -R,trash-put 则不需要。 trash-put 了,真的不能给 rm 设置别名吗? # 你可以给 rm 设置一个别名来提醒你不要使用它: alias rm='echo "This is not the command you are looking for."; false' 如果你真的要用 rm,那就在 rm 前加上斜杠来取消别名: \rm file-without-hope 注意,Bash 别名是有在交互式界面才有效,所以使用这个别名不会影响使用 rm 的脚本。 # 从 home 分区移动到回收站的文件在这: ~/.local/share/Trash/ # 简单方法 # - Python 3 (Python 2.7 may work) > - pip (use *apt-get install python-pip* on Debian) --> 要求: Python 3 (Python 2.7 也可以) pip (在 Debian 上用 apt-get install python-pip 来安装 pip) 安装命令: pip install trash-cli # 为所有用户安装: git clone https://github.com/andreafrancia/trash-cli.git cd trash-cli sudo pip install . 为当前用户安装: git clone https://github.com/andreafrancia/trash-cli.git cd trash-cli pip install . 为当前用户安装后你可能需要把以下代码添加到 .bashrc: export PATH=~/.local/bin:"$PATH" 卸载命令: pip uninstall trash-cli # Debian/Ubuntu (apt): sudo apt install trash-cli # . On Twitter I'm @andreafrancia. --> 如果你发现了 bug,请在这里报告: https://github.com/andreafrancia/trash-cli/issues 你也可以给我发邮件 andrea@andreafrancia.it。我的推特帐号是 @andreafrancia。 # 环境设置: virtualenv env --no-site-packages source env/bin/activate pip install -r requirements-dev.txt 运行测试: nosetests unit_tests # 只运行单元测试 nosetests integration_tests # 运行所有集成测试 nosetests -A 'not stress_test' # 运行压力测试以外的测试 nosetests # 运行所有测试 发布前检测安装进程: python check_release_installation.py | stats.svg open stats.svg --> 单元测试性能分析: pip install gprof2dot nosetests --with-profile --profile-stats-file stats.pf --profile-restrict=unit_tests unit_tests gprof2dot -w -f pstats stats.pf | dot -Tsvg >| stats.svg open stats.svg

2020/12/12
articleCard.readMore

免费使用知网

市级和省级图书馆的网站都有知网资源,注册帐号之后登陆就可以免费使用。以广州图书馆为例,先登陆帐号,点击首页 -> 资源 -> 数字资源导航,点击打开中国知网就可以免费下载论文了。 吐槽一下中国知网,博硕士论文只有 CAJ 格式,英文版知网才能下载 PDF 格式的博硕士论文。中国知网宁愿方便外国人也不愿方便方便国人。看看 CAJViewer for Linux 的显示效果,模糊至极,简直是不堪入目。 既然如此,咱们就只好装作洋大人,用英文版知网下载清晰的 PDF 论文。以下面这篇论文为例,演示下载步骤。 首先在首页选择 ENGLISH: 然后直接搜索中文标题: 点击 Download the Full-text(PDF) 就可以下载了。 部分图书馆会限制外地人注册,比如注册广州图书馆需要广州身份证、广州社保卡或者长期居住证明材料,不在广州生活的人就很难注册。注册的时候要看清楚条款,免得白忙活一趟。最省事的方法就是用注册浙江图书馆,外地人也能注册,在支付宝直接授权就能注册。 操作步骤:在支付宝关注浙江图书馆生活号,浙江图书馆生活号 -> 服务 -> 服务大厅 -> 新用户注册 -> 确定授权。 参考资料:在家里如何免费使用中国知网? - 知乎

2020/12/10
articleCard.readMore

增强计算机安全性的技巧

关闭 BIOS 的 USB Boot 和 PXE Boot 选项 # 开启了 USB 启动后,用户可以绕过电脑里的操作系统,直接启动 U 盘里面的系统。PXE Boot 则是通过网络接口启动计算机。这样不需要知道原系统密码也可以读取硬盘里的文件了。我觉得这两个功能还挺危险的,平时我都会关闭它们,装系统的时候才用 USB Boot,用完就关闭。除此之外,还要设置 BIOS 密码,不然别人拿到你的电脑一样可以开启这两个选项。 # 这个技巧是针对 Linux 的。GRUB 的 recovery mode 可以让用户不需要密码的情况下使用 root 账户。这个功能实在是太强力了,输入几条命令就可以修改用户密码。解决这个问题的办法就是:先设置 BIOS 密码,再设置启动电脑时询问 BIOS 密码。 # 设置了 BIOS 并不意味着可以高枕无忧。别人拿到你的电脑虽然不能直接在里面启动系统,但是可以把硬盘拆下来放到另一台电脑中读取文件。但是也不要担心,办法还是有的。使用 BitLocker 这样的全盘加密技术,别人拆下你的硬盘也无法读取你的文件。 # 除了前面几个技巧,保持良好习惯也很重要。比如:到官网下载软件、不要访问证书错误的网站。 # 基本输入输出系统(Basic Input/Output System,BIOS) 统一可扩展固件接口(Unified Extensible Firmware Interface,UEFI) 网络引导(Network booting) 预启动执行环境(Preboot eXecution Environment,PXE)

2020/12/8
articleCard.readMore

GitHub/jsDelivr 图床教程

因为在博客的源代码仓库加图片(二进制文件)会导致仓库变大,所以我就把图片放到另一个仓库,直接使用链接来引用图片。 新建公共仓库1 勾选 Add a README file,这样待会就可以直接使用了,点击 Create repository 克隆仓库 1 git clone git@github.com:your-username/repo-name.git 添加一些图片到仓库 上传图片 1 2 3 4 #!/usr/bin/env sh git add --all git commit -m "update" git push 获取链接 我们可以使用 GitHub 的链接或者 jsDelivr CDN,前者在中国被封禁,后者还能用。jsDelivr 会缓存文件,如果更新了文件,需要清除缓存。 GitHub 链接规则:https://raw.githubusercontent.com/${用户名}/${仓库名}/${分支名}/${路径} jsDelivr 链接规则:https://cdn.jsdelivr.net/gh/${用户名}/${仓库名}@${分支名}/${路径} jsDelivr 清除缓存链接规则:https://purge.jsdelivr.net/gh/${用户名}/${仓库名}@${分支名}/${路径}。 举个例子,https://github.com/CyrusYip/blog-static/blob/main/images/2020-11-06_fcitx5-unicode.gif 这个文件对应的链接为: GitHub:https://raw.githubusercontent.com/CyrusYip/blog-static/main/images/2020-11-06_fcitx5-unicode.gif jsDelivr:https://cdn.jsdelivr.net/gh/CyrusYip/blog-static@main/images/2020-11-06_fcitx5-unicode.gif jsDelivr 清除缓存:https://purge.jsdelivr.net/gh/CyrusYip/blog-static@main/images/2020-11-06_fcitx5-unicode.gif 把链接放到 Markdown 文件里就可以使用了。比如:![](https://raw.githubusercontent.com/CyrusYip/blog-static/main/images/2020-11-06_fcitx5-unicode.gif)。 删除文件请参考《完全删除 Git 仓库的文件》 自己手动拼凑链接太费劲,我写了个 Bash 程序来获取文件链接并将其写入 X11 剪贴板(使用 fzf 模糊搜索,找文件很快)。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 #!/usr/bin/env bash # Get raw file links from current GitHub repository # Dependencies: fzf and xclip # This file should be placed at the root of a repository # Guide (Chinese): https://cyrusyip.org/zh-cn/post/2020/12/05/host-images-on-github/ username="CyrusYip" repo_name="blog-static" branch_name="main" get_url() { path=$(fzf) github="https://raw.githubusercontent.com/${username}/${repo_name}/${branch_name}/${path}" jsdelivr="https://cdn.jsdelivr.net/gh/${username}/${repo_name}@${branch_name}/${path}" jsdelivr_purge="https://purge.jsdelivr.net/gh/${username}/${repo_name}@${branch_name}/${path}" # copy all links so I can get them later copy_count=0 echo "$github" | xclip -selection clipboard && copy_count=$((copy_count + 1)) echo "$jsdelivr_purge" | xclip -selection clipboard && copy_count=$((copy_count + 1)) echo "$jsdelivr" | xclip -selection clipboard && copy_count=$((copy_count + 1)) [ $copy_count -eq 3 ] && echo "Links were successively copied." echo -e "\nLinks for the file:" echo " $github" echo " $jsdelivr" echo " $jsdelivr_purge" echo -e "\nPress Ctrl-C to exit, Enter to contine..." } while true; do get_url read -r done 建议遵守 GitHub 和 jsDelivr 的使用条款,以免服务终止。 GitHub 合理使用政策 jsDelivr 使用条款(重点看 Prohibited Use) 私人仓库需要令牌(token)访问图片,但是令牌会自动刷新,刷新后就无法使用之前的网址。想用私人仓库可以考虑使用 Cloudflare Pages 这样的 Jamstack 服务部署图片到子域名(例如 images.cyrusyip.org)。 ↩︎

2020/12/5
articleCard.readMore

在 Windows 下修复 U 盘错误

有时在 Windows 插入 U 盘会提示有错误需要修复,我一直都是忽略的,接着用 U 盘。今天用 U 盘的时候没办法打开一个文件夹,于是就乖乖地修复了 U 盘,修复完就好了。原来 Windows 的 U 盘修复那么有用。 修复方法:在文件资源管理器右击 U 盘,点击 Properties -> Tools -> Error checking -> Check。

2020/12/1
articleCard.readMore

大学咸鱼指北

工地大学 # 读高中的时候,老师常说:「现在加把劲,上了大学就轻松了。」上大学之后马上就发现老师说的都是屁话啊,上大学也挺累的啊。我就读的工地大学1居然有早自习,而且是要 7 点半到课室。为什么要那么早起床呢,学生不会自己安排生活吗,就差那半小时自习?经历了 12 年的「尊师教育」,刚上大学的时候还是比较乖的,学校怎么说我就怎么做。 上大学之后的第一件事就是军训。因为男生要剪寸头,然后我就和长发说再见了,真的是又生气又无奈。军训说是可以强身健体,我感觉完全是「驯服教育」,让大一新生好好听话。我那时候脚痛,在后勤部休息,也没躲过辅导员的驯服教育。那会的辅导员真该死,居然叫脚痛的我去搬桶装水。辅导员官威很重,看不得伤员休闲的样子,非要过来让我们站军姿和坐军姿。 经历完军训,开始正是上课之后又是一堆作业要做。还有每日打卡的学习任务,做完之后要在微信群报告,没做就一直催促。没多久就遇到了工地大学臭名昭著的素质培养计划。素培计划要求学生通过参加活动积累够 160 个学分,不然不能毕业。听一个讲座才 0.5 学分,只听讲座岂不是 听 320 个才行?好家伙,同学一听到不够素培学分不能毕业,都争先恐后地报名参加活动。每个学校举行的活动都坐无虚席,有不少是玩手机的。我猜真正想参加活动的同学估计还抢不到名额,去听讲座的反而是换个地方玩手机的,真是荒诞。 上课没意思,作业又多,杂事又多。工地大学的生活实在是太无聊了。于是我就打算做一条咸鱼,用尽量少的努力混到毕业。考试 60 分万岁,能不做的事情都不做,剩下的时候打打游戏,读读书。 # 既然对专业不感兴趣,那就做一条咸鱼吧。本文对咸鱼的定义是「尽量省事地完成学业混个毕业证,剩下的时间用于做自己喜欢的事情」。下面的内容是建立在一个前提之上的:上大学只拿毕业证,不做其他有求于学校的事情(比如申请奖学金、申请成为党员)。只要不有求于学校,就可以忽略它的要求了。 首先,做咸鱼呢,只要完成毕业要求就好了,其他的事情一概不管。最基本的就是学分要求,一定要保证每门课都修到学分。每门课的第一节课好好听考核要求,关注以下方面:考核组成、能否补考。平时上课可以摸下鱼,但是最后考试周最好加把劲复习一次搞定。如果挂科了也别慌,继续复习补考便是。不能补考直接重修的课就很麻烦了,所以要注意上的课能不能补考。虽然说 60 分万岁,但是不小心考到 59 就很悲惨了。 不要参加社团和部门,这样可以剩下很多时间。当然了,如果社团就是你的兴趣所在的话,参加也无妨。如果参加之后发现不适合就感觉退出。要是中途退出被要求写超长的退出申请的话,别怕,直接退群不参加活动便是。社团并不能拿你怎么着。 有时候做咸鱼是很艰难的,学校会逼着你去做一些没用的事情。大学想逼学生去做事,无非就是把一件事和毕业挂钩,通过对学生施加恐惧与焦虑,让学生去做事情。比如「不做志愿,没有志愿学时,就不能毕业」。这些话,有些是真的,有些是假的。获取学位证的要求应该参考学生手册,而不是辅导员的屁话。想要不被吓到,一定要保持批判性思维,敢于怀疑听到的话语。 比如前面提到的早自习。学校只要求必须去早读是没用的,一听就知道没什么后果对吧。所以工地大学的辅导员会恐吓学生,说 3 次不去早自习就等于 1 次旷课,还会被记名。部分新生听到可能就很慌,心想:我经常不去早自习 -> 会旷课好多次 -> 旷课多了就挂科了。一旦这么想就慌张了,人不喜欢焦虑的状态,于是就通过参加早自习来消除这份焦虑。 停下来好好看看辅导员的话: 3 次不去早自习就等于 1 次旷课。 假设它是真的,如果你真的有 3 次没去,会怎么样呢?会旷课 1 次,可是你有那么多门课,要给你记哪门课的旷课呢?是不是越想越奇怪,上面那句话完全没有可行性嘛。其实对于学校的安排,应该考虑它的真实性和后果,而不是被恐惧左右你的选择。就继续分析早自习的例子吧,辅导员说不去早自习就等于旷课。首先,辅导员没有这样的权利,其次它也不具备可行性,所以这句话是假的。 下面再分析一下前面提到的素质培养计划(简称素培): 学生必须积累 160 个素培学分,方可毕业。 往届的学生也是要搞这个的,就当素培是真的吧。获取素培学分最基本的方法就是听讲座,但是才 0.5 个学分。参加活动与组织活动分数更高,但机会有限,还费时费力。根据我的回忆,我们学院每学期大概有 20 场讲座,每场讲座需要 30 位观众,然后学生在学校待 7 个学期。讲座可以提供 20×30=4200 个学分。我们学院有 450 人。平分一下每个人才 4200/450≈9.3 个学分,完全不够用嘛。 很多同学也觉得这个素培计划过于苛刻,但又因为害怕毕不了业就争先恐后地报名活动,然后就换个地方玩手机。在这里先引入一条「公理」: 大学是营利机构,不会做损坏自己利益的事情。 苛刻的素培计划完全是违背公理的,如果让 99% 的学生都不能毕业,那谁还会报考工地大学呢,没人报考工地大学,工地大学不就倒闭了吗?但是根据往届学生的陈述,这又确实是毕业的要求之一。难不成素培计划是假的。我只能说它是半真半假,确实需要素培学分才能毕业,但是考虑到大多数人的状况,学校会在某个时候降低要求。 果不其然,在大四的时候,工地大学把素培学分要求降低到了 130。平时有些班级活动有比较高的素培学分,所以多数同学不用怎么参加素培活动都够分了。估计不少同学知道这个消息之后,内心骂了 100 遍工地大学。我也觉得工地大学真他妈奸诈,总是利用学生的单纯,通过恐吓来逼迫学生参加活动。像我这种老咸鱼,慌张了一会就会觉得素培计划很荒诞,然后该干嘛干嘛。可是那些最慌张的同学,就这样被骗了三四年,参加活动浪费那么多时间,真替他们感到不值。 工地大学辅导员惯用的恐吓词语还有「必须」和「后果自负」。识破辅导员诡计的方法就是想想不服从安排的后果。以下面的通知为例: 四级没考过的同学必须参加明天的四级备考讲座,否则后果自负! 这句话没有提及不参加的后果,所以「后果自负」是废话,不过有一定的恐吓效果。「必须」其实也是废话啊,辅导员又不能拿刀放到学生的脖子上逼着他去吧。 其实写这份指北,不是想鼓励大家做只是混毕业证的学生,而是给机会自己探索一下其他可能。 # 选择做咸鱼之后,会有比较多的空闲时间。空闲起来没事做,人会迷茫。买了 Nintendo Switch 打游戏,打游戏挺快乐的,但是玩多了又觉得空虚。想学计算机,犹豫了很久,终于在大三尝试了学 Python。先学了Python Crash Course, 2nd Edition,还发现了 Open Source Society University 的计算机科学课程,感觉自学计算机科学确实可行。学 Python 的时候会根据自己的需求写一些程序给自己用,那种创作的快乐真是让我着迷。 之后就是对什么感兴趣就学什么,学了杂七杂八的东西:Markdown、Git、Github、HTML、LaTeX、Rmarkdown。还给自己注册了个域名,用 Blogdown 写日志。学计算机之后,我再也没玩过 Switch,因为觉得学计算机技术太有意思了。Switch 应该都有 10 个月没开机的,居然毫不费力就不打游戏了,真不可思议。 学计算机的过程中,我发现有些简洁又强大的技术,比如 Markdown 和正则表达式。我很喜欢 Markdown 的简洁,内容与样式分离的写作方法也让我受益匪浅,治好了改格式的强迫症。用 Markdown 写作简直是种享受。Rmarkdown 就更强大了,可以用来写书、写幻灯片、写博客。Markdown 也不难学, CommonMark 的语法 10 分钟就能学完。我大学不是计算机专业的,学了这些技术,觉得十分有用。只有学计算机的人用这些技术太可惜啦,希望有一天可以在普通人中推广 Markdown、Rmarkdown和正则表达式。 我读的计算机资料大多是英文的,真的很感谢迷茫时努力的自己,不然我读英文肯定很吃力。我大学读的是英语专业,不过我实在是对文学和语言学不感兴趣,一度觉得上专业课十分痛苦。在那些迷茫的日子,虽然我经常不听专业课,但也在认真学英文,读了一些英文原版书,积累了不少词汇。或许迷茫的时候做好当下的事情也是一个不错的策略,如果我没有读那些原版书增加词汇量,就没机会读英文的资料了。感谢努力的自己。 我就读的大学会在开学期间搞装修搞建设,一点都不尊重学生。挖掘机地面挖得坑坑洼洼,有时候得绕路。感觉自己就在工地上大学,所以把这所大学称为「工地大学」。 ↩︎

2020/11/28
articleCard.readMore

正则表达式实例

2024 年 3 月 31 日更新:像有序列表和无序列表互换这样比较简单的问题,现在我都用 Vim 处理,不想费脑筋想正则了。 本文记录了我使用过的正则表达式,多数用于处理 Markdown 文档。所有正则表达式均在 VSCode 测试。 # 有时候我要选取很多段文字,比如某本书的一个章节。以前我选取多段文字都是这样的: 把光标定位到开头 按下 Shift 滚动文档到结尾 点击一下结尾 有时候这个招数不太好使,滚动文档的时候也不知道有没有超过了结尾。还是用正则表达式好,不用担心错过了结尾。 以下面的文档作例子,截取第一章的内容: 1 2 3 4 5 6 7 8 9 # 第一章 假设这里有好长的一段话。 假设这里又有好长的一段话。 # 第二章 又来一段话。 也就是: 1 2 3 假设这里有好长的一段话。 假设这里又有好长的一段话。 表达式: 1 (?<=# 第一章\n{2})(.|\n)+(?=\n{2}# 第二章) (?<=) 为正后发断言(Positive Lookbehind),匹配它后面的内容。(?<=# 第一章\n{2}) 的意思是匹配第一章加两个换行之后的内容。 (?=) 后正先行断言(Positive Lookahead),匹配它前面的内容。(?=\n{2}# 第二章)的意思就是匹配两个换行加第二章。 我们真正需要的文本包括了文字和换行,所以用 (.|\n)+ 来匹配。 # # 假如我有两门课的笔记,需要把它们合并到一块。 把这两份笔记: 1 2 3 4 5 6 7 8 9 10 11 --- title: 算术 --- # 加法 加法是基本算术运算。简单来说,加法将两个数字结合,成为一个数字,称之为“和”。 # 减法 减法是加法的逆运算。减法是求出两个数(被减数和减数)的差。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 --- title: 几何 --- # 点 在欧几里得几何中,点是空间中只有位置,没有大小的图形。 # 线 欧几里得把线形容成“在点之间均匀铺着”的“没有宽度的长度”。 # 面 二维,光滑且无限延展的平层构成了平面。 合并为(title: 数学 这一部分需要手动输入): 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 --- title: 数学 --- # 算术 ## 加法 加法是基本算术运算。简单来说,加法将两个数字结合,成为一个数字,称之为“和”。 ## 减法 减法是加法的逆运算。减法是求出两个数(被减数和减数)的差。 ## 点 在欧几里得几何中,点是空间中只有位置,没有大小的图形。 # 几何 ## 线 欧几里得把线形容成“在点之间均匀铺着”的“没有宽度的长度”。 ## 面 二维,光滑且无限延展的平层构成了平面。 解决思路: 内容标题等级 + 1 把文档标题变成一级标题。 以算术笔记为例: 1 2 3 4 5 6 7 8 9 10 11 --- title: 算术 --- # 加法 加法是基本算术运算。简单来说,加法将两个数字结合,成为一个数字,称之为“和”。 # 减法 减法是加法的逆运算。减法是求出两个数(被减数和减数)的差。 内容标题等级 + 1 搜索 ^#,替换为 $0#,其实也就是给标题加多个 # 把文档标题变成一级标题 搜索 ---\ntitle: (.+)\n---,替换为 # $1 处理完之后算术笔记就变成这样了: 1 2 3 4 5 6 7 8 9 # 算术 ## 加法 加法是基本算术运算。简单来说,加法将两个数字结合,成为一个数字,称之为“和”。 ## 减法 减法是加法的逆运算。减法是求出两个数(被减数和减数)的差。 用同样的方法处理几何笔记: 1 2 3 4 5 6 7 8 9 10 11 # 几何 ## 点 在欧几里得几何中,点是空间中只有位置,没有大小的图形。 ## 线 欧几里得把线形容成“在点之间均匀铺着”的“没有宽度的长度”。 ## 二维,光滑且无限延展的平层构成了平面。 最后新建一个文档,手动输入 title: 数学,再把两份处理好的文档复制进去就可以了。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 --- title: 数学 --- # 算术 ## 加法 加法是基本算术运算。简单来说,加法将两个数字结合,成为一个数字,称之为“和”。 ## 减法 减法是加法的逆运算。减法是求出两个数(被减数和减数)的差。 ## 点 在欧几里得几何中,点是空间中只有位置,没有大小的图形。 # 几何 ## 线 欧几里得把线形容成“在点之间均匀铺着”的“没有宽度的长度”。 ## 面 二维,光滑且无限延展的平层构成了平面。 # 我们用上个教程合并的文档为例子: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 --- title: 数学 --- # 算术 ## 加法 加法是基本算术运算。简单来说,加法将两个数字结合,成为一个数字,称之为“和”。 ## 减法 减法是加法的逆运算。减法是求出两个数(被减数和减数)的差。 ## 点 在欧几里得几何中,点是空间中只有位置,没有大小的图形。 # 几何 ## 线 欧几里得把线形容成“在点之间均匀铺着”的“没有宽度的长度”。 ## 面 二维,光滑且无限延展的平层构成了平面。 将其拆分为两份文档: 1 2 3 4 5 6 7 8 9 10 11 --- title: 算术 --- # 加法 加法是基本算术运算。简单来说,加法将两个数字结合,成为一个数字,称之为“和”。 # 减法 减法是加法的逆运算。减法是求出两个数(被减数和减数)的差。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 --- title: 几何 --- # 点 在欧几里得几何中,点是空间中只有位置,没有大小的图形。 # 线 欧几里得把线形容成“在点之间均匀铺着”的“没有宽度的长度”。 # 面 二维,光滑且无限延展的平层构成了平面。 解决思路: 删除文档标题 把一级标题变成文档标题 内容标题等级 - 1 具体步骤: 删除文档标题 搜索 ---\ntitle:.+\n---\n\n,替换为 空字符串 把一级标题变成文档标题 搜索 ^# (.+) ,替换为 ---\ntitle: $1\n--- 内容标题 - 1 搜索 ^#,替换为 空字符串。 结果: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 --- title: 算术 --- # 加法 加法是基本算术运算。简单来说,加法将两个数字结合,成为一个数字,称之为“和”。 # 减法 减法是加法的逆运算。减法是求出两个数(被减数和减数)的差。 # 点 在欧几里得几何中,点是空间中只有位置,没有大小的图形。 --- title: 几何 --- # 线 欧几里得把线形容成“在点之间均匀铺着”的“没有宽度的长度”。 # 面 二维,光滑且无限延展的平层构成了平面。 最后把内容复制到两个空文档就可以了。 # 虽然用正则表达式可以转换列表,其实我觉得 Typora 的列表转换功能更方便,点一下按钮就可以了。 # 把下面的有序列表转换为无序列表: 1 2 3 4 5 水果: 1. 香蕉 2. 椰子 3. 葡萄 搜索 \d+\.(?= ),替换为 -: 1 2 3 4 5 水果: - 香蕉 - 椰子 - 葡萄 # 有序列表的数字不需要递增,实际上是从第一个数字开始递增的。 比如下面这几个列表显示效果是一样的: 1 2 3 4 5 水果: 11. 香蕉 12. 椰子 13. 葡萄 1 2 3 4 5 水果: 11. 香蕉 1. 椰子 1. 葡萄 1 2 3 4 5 水果: 11. 香蕉 11. 椰子 11. 葡萄 都会显示为: 水果: 香蕉 椰子 葡萄 把下面的无序列表转换为从 2 数起的有序列表: 1 2 3 4 5 水果: - 香蕉 - 椰子 - 葡萄 搜索 -(?= ),转换为 2.: 1 2 3 4 5 水果: 2. 香蕉 2. 椰子 2. 葡萄 # # 在 Markdown 中使用多个空行不会增加段落间的空白,下面两份文档显示效果是一样的: 1 2 3 4 5 6 7 # 加法 加法是基本算术运算。 # 减法 减法是加法的逆运算。 1 2 3 4 5 6 7 8 9 10 11 # 加法 加法是基本算术运算。 # 减法 减法是加法的逆运算。 因此,可以删去多余的空行。以上面的文档为例,演示删除多余的空行。 搜索 \n{2,},替换为 \n\n。 # 有些纯文本文档用一个换行符来分段,增加空行可以快速将其转换为 Markdown 文档。以下面的文档为例子: 1 2 3 4 加法 加法是基本算术运算。 减法 减法是加法的逆运算。 搜索 \n,替换为 \n\n: 1 2 3 4 5 6 7 加法 加法是基本算术运算。 减法 减法是加法的逆运算。 # 一般写论文都是用 Word 自动编号的,知网文献的编号没什么用,所以就先把编号删掉。 1 2 [1]黄城烟.参考文献中标准著录格式的新规定及其影响——以GB/T7714―2015为例[J].中国科技期刊研究,2016,27(03):243-248. [2]韩云波,蒋登科.参考文献国家标准GB/T7714—2015的修订特色与细则商榷[J].西南大学学报(社会科学版),2015,41(06):157-167. 在 LibreOffice Writer 按下 Ctrl H,搜索 \[\d+\],替换为空字符串。在 MS Word 里面应该搜索 \[[0-9]@\]。替换后之后文献前的数字就没有了: 1 2 黄城烟.参考文献中标准著录格式的新规定及其影响——以GB/T7714―2015为例[J].中国科技期刊研究,2016,27(03):243-248. 韩云波,蒋登科.参考文献国家标准GB/T7714—2015的修订特色与细则商榷[J].西南大学学报(社会科学版),2015,41(06):157-167. # 在扫描版 PDF 中查找内容

2020/11/26
articleCard.readMore

中文没有斜体

在西文中,意大利体(italic type)是手写风格的字体,常用作强调内容。西文中还有另一种倾斜的字体是伪斜体(oblique type),它的形状和常规字体一样,只是向右倾斜了。伪斜体和意大利体一样用作强调。下图为常规字体(罗马体)、意大利体与伪斜体(Garamond Roman): 罗马体(Roman type)和意大利体(Italic type)示例 伪斜体(oblique type)示例 中文里没有「斜体」(意大利体、伪斜体)的概念,所以千万不要照搬西文的习惯,用斜体来强调中文内容。斜体中文既错误又丑陋。可以用粗体或楷体来强调中文内容,正文内容用宋体或黑体。楷体看起来比较温和,粗体更为突出。 LaTeX 的 ctex 宏包对强调中文的处理挺不错的,用了 ctex 文档类或宏包之后,正文是宋体,\emph{中文} 是楷体,\textbf{中文} 是黑体。 1 2 3 4 5 6 \documentclass[fontset=windows]{ctexart} \begin{document} 你好 \emph{你好} \textbf{你好} \textbf{\emph{你好}} Hi \emph{Hi} \textbf{Hi} \textbf{\emph{Hi}} \end{document} ctex 中文示例

2020/11/26
articleCard.readMore

修复 Kubuntu 无音频设备的问题

执行命令: 1 2 3 4 #!/bin/bash -x sudo alsa force-reload pulseaudio -k start-pulseaudio-x11 进入 System Settings -> Hardware -> Audio -> Advanced -> Device Profiles,把 Profile 改成 Analog Stereo Duplex。 把重置音频的命令保存为脚本文件,以后使用更方便: 把开头的脚本保存为 reset-sound 添加执行权限 chmod +x reset-sound 把文件放到 $PATH1 目录中 这样以后出问题了就不用回来看那几行命令了,直接在终端执行 reset-sound 就行。 延伸阅读: (K)Ubuntu 17.10 - No Audio devices found, no settings, no sound 如果你没有建立目录存放自己用的脚本,那就使用 mkdir ~/bin 建立一个,然后把 export PATH="/home/hunter/bin:$PATH" 添加到 .bashrc 和 .zshrc。 ↩︎

2020/11/24
articleCard.readMore

KDE Plasma 开机静音设置

Kubuntu 休眠之后开机总会报错: 1 2 3 4 5 6 7 Message from syslogd@my-pc at Nov 15 09:31:33 ... kernel:[ 319.150050] Do you have a strange power saving mode enabled? Message from syslogd@my-pc at Nov 15 09:31:33 ... kernel:[ 319.150050] Dazed and confused, but trying to continue Message from syslogd@my-pc at Nov 15 09:31:33 ... kernel:[ 319.150049] Uhhuh. NMI received for unknown reason 2d on CPU 0. 在 Stack Exchange 搜索了一下,没发现什么简单的解决方法,于是就一直忍着。但是在教室或者图书馆的时候,打开电脑,突然间它发出了响亮的「噔」警报声。旁人的目光让我的社交焦虑值飙升,巴不得找个洞钻进去。关注的眼神实在是太可怕了!我还是想办法解决这个问题吧。既然没办法阻止报错,那就只能开机和解锁的时候设置静音了。 在 Ask Ubuntu 找到了设置音量的命令: 1 2 3 /usr/bin/pactl set-sink-volume 0 100% # or /usr/bin/amixer -D pulse sset Master 100% 接下来就可以开始设置静音了。 # # 1 2 3 4 5 6 7 8 mkdir ~/.config/autostart-scripts cd ~/.config/autostart-scripts echo "#\!/bin/bash /usr/bin/pactl set-sink-volume 0 0%" > 0-vol.sh chmod +x 0-vol.sh # 点击 System Settings -> Workspace -> Startup and Shutdown -> Autostart -> Add Script,直接在设置搜索 Autostart 也行,添加的脚本内容如下: 1 2 #!/bin/bash /usr/bin/pactl set-sink-volume 0 0% 休眠后再开机,发现没有静音。经过测试,发现这个方法只适用于关机之后开机。可能从休眠中启动只是把硬盘中保存的东西再重新放入内存,所以并不算开机吧。从休眠中启动完之后会进入解锁界面,所以要设置锁屏静音。 # 这个设置我只找到了 GUI 的方法,同样是在系统设置。 进入设置 System Settings -> Personalization -> Notifications -> Applications -> Screen Saver 选择 Screen locked 在 Run command 选项添加前面的静音脚本 ~/.config/autostart-scripts/0-vol.sh 终于可以不听到这烦人的提示音了!写到这里发现应该只设置锁屏静音就行了,不需要设置开机静音。懒得测试了,就这样吧。

2020/11/15
articleCard.readMore

在 Ubuntu 下配置 Fcitx5

安装 # 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 # 安装 Fcitx5 sudo apt install fcitx5 \ fcitx5-pinyin \ fcitx5-chinese-addons \ fcitx5-frontend-gtk2 \ fcitx5-frontend-gtk3 \ fcitx5-frontend-qt5 \ fcitx5-module-ibus \ fcitx5-module-cloudpinyin \ fcitx5-material-color # 把 Fcitx5 设置为默认输入法 im-config -n fcitx5 # 设置 Fcitx5 拼音输入法 fcitx5-configtool # 开机启动 cp /usr/share/applications/fcitx5.desktop ~/.config/autostart/ # # Fcitx5 默认的标点符号键位为: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 $ cat /usr/share/fcitx5/punctuation/punc.mb.zh_CN . 。 , , ? ? " “ ” : : ; ; ' ‘ ’ < 《 > 》 \ 、 ! ! $ ¥ ^ …… * × _ —— ( ( ) ) [ · ] 「 」 ~ ~ 因为我常用 Markdown 和直角引号,所以把原本是弯引号的键位改成了直角引号,把方括号的键位改成了弯引号,取消了乘号和分隔符。如果要输入乘号和分隔符,就按下 Ctrl + Alt + Shift + u,输入multiplication sign 或 middle dot(用对应的 Unicode 码也行);使用 Tab 和 Shift Tab 选择、↑ 和 ↓ 翻页,Enter 确定。 其他键盘上没有的字符也可以用这个方式输入,选中字符后按下 Ctrl + Alt + Shift + u 就可以获取字符名称。 设置方法: 建立新的配置文件 1 2 3 mkdir ~/.local/share/fcitx5/punctuation/ touch ~/.local/share/fcitx5/punctuation/punc.mb.zh_CN nano ~/.local/share/fcitx5/punctuation/punc.mb.zh_CN 把下面的配置内容复制进去: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 . 。 , , ? ? " 「 」 : : ; ; ' 『 』 < 《 > 》 \ 、 ! ! $ ¥ ^ …… _ —— ( ( ) ) [ ‘ ’ ] “ ” ~ ~ 重启 Fcitx5 1 pkill fcitx5 && fcitx5 & 变化如下: 1 2 3 4 5 6 7 8 9 10 $ icdiff punc.mb.zh_CN.old punc.mb.zh_CN.new -U 0 punc.mb.zh_CN.old punc.mb.zh_CN.new " “ ” " 「 」 --- --- ' ‘ ’ ' 『 』 --- --- * × --- --- [ · [ ‘ ’ ] 「 」 ] “ ” # 下载词库(这里很久没更新了,目前可以下载 Arch Linux 的 fcitx5-pinyin-zhwiki,解压后词典路径为fcitx5-pinyin-zhwiki-1_0.2.4.20240210-1-any.pkg/usr/share/fcitx5/pinyin/dictionaries/zhwiki.dict) 添加词库 1 2 sudo mkdir /usr/share/fcitx5/pinyin/dictionaries # 建立词库目录 sudo cp zhwiki.dict /usr/share/fcitx5/pinyin/dictionaries # 添加词库 重启 Fcitx5 1 pkill fcitx5 && fcitx5 &

2020/11/6
articleCard.readMore

在扫描版 PDF 中查找内容

扫描版的 PDF 都是图片,在里面查找内容是不可能的。所以「在扫描版 PDF 文档中查找内容」这个问题可以拆解为两部分:一是识别 PDF 中的文字,二是搜索里面的内容。 # 开始教程之前,先安装好需要的软件: 1 2 3 4 5 6 7 8 9 10 11 12 # OCRmyPDF sudo apt install ocrmypdf # 语言支持 sudo apt install tesseract-ocr-eng \ tesseract-ocr-chi-sim # pdftotext sudo apt install poppler-utils # VS Code # 这个得到官网下载:https://code.visualstudio.com/ # 首先,我们要用 OCR1 技术来识别 PDF 中的文字。有很多 OCR 软件,我用的是 OCRmyPDF。接下来用余光中译的《老人与海》作为例子。 识别 PDF 文档中的文字 1 ocrmypdf -l eng+chi_sim 老人与海-余光中.pdf 老人与海-余光中-ocr.pdf 把识别后 PDF 转换成纯文本 1 pdftotext 老人与海-余光中-ocr.pdf # # 《老人与海》第三段 除了眼睛,他身上处处都显得苍老。可是他的眼睛跟海水一样颜色,活泼而坚定 在 老人与海-余光中-ocr.txt 里面是这样的: 1 2 3 4 除了 眼睛, 他 身上 处 处 都 显得 苍老.可 是他 的眼睛 跟 海 水一 样 颜色 , 活 涛 而 坚定 。 可见文字识别的效果实在不太行,不仅有错字,还有多余的空格和换行。直接搜索想找的内容肯定是不行的,但是正则表达式就可以。先观察一下上面那段文字,有文字、空格和换行符,共 58 个字符。所以我们要查找带有包含文字、空格和换行的组合。 使用 VS Code 查找: 1 [除了眼睛,他身上处处都显得苍老。可是他的眼睛跟海水一样颜色,活泼而坚定 \n]{10,} 结果: 1 2 3 一 样苍老 。 除了 眼睛, 他 身上 处 处 都 显得 苍老.可 是他 的眼睛 跟 海 水一 样 颜色 把结果复制到 WPS PDF 搜索,就可以找到第三段文字了。注意,不推荐用 grep 搜索,grep 只能搜索一行字符。 # 第三段的英文 Everything about him was old except his eyes and they were the same color as the sea and were cheerful and undefeated. 在 老人与海-余光中-ocr.txt 里面是这样的: 1 2 Everything about him was old except his eyes and they were the same color as the sea and were cheerful and undefeated. 看来识别效果挺好的,内容正确。单词间的都是空格或者换行符。使用 VS Code 查找: 1 Everything(\n| )*about(\n| )*him(\n| )*was(\n| )*old(\n| )*except(\n| )*his(\n| )*eyes(\n| )*and(\n| )*they(\n| )*were(\n| )*the(\n| )*same(\n| )*color(\n| )*as(\n| )*the(\n| )*sea(\n| )*and(\n| )*were(\n| )*cheerful(\n| )*and(\n| )*undefeated\. (把 Everything about him was old except his eyes and they were the same color as the sea and were cheerful and undefeated. 的空格代替为 (\n| )*,再在句号前加上反斜杠,这样就得到上面的表达式了。) 结果: 1 2 Everything about him was old except his eyes and they were the same color as the sea and were cheerful and undefeated. Optical Character Recognition,光学字符识别 ↩︎

2020/11/5
articleCard.readMore

在 RStudio 中使用 Fcitx5(Kubuntu 20.10)

2022 年 7 月 16 日更新:Electron 版的 RStudio 可以正常使用 Fcitx5 了,位置也正常。 在 Kubuntu 20.10 使用 RStudio 的时候,发现它不支持 Fcitx。参考 RStudio 官方的方法,成功在 RStudio 里面用上了 Fcitx 5。里面部分内容已经过时,应该用下面这个命令才对: 1 sudo ln -s /usr/lib/$(dpkg-architecture -qDEB_BUILD_MULTIARCH)/qt5/plugins/platforminputcontexts/libfcitxplatforminputcontextplugin.so /usr/lib/rstudio/plugins/platforminputcontexts 最近把 Kubuntu 20.04 升级到了 20.10,结果无法在 RStudio 中使用 Fcitx5 了。可恶,为什么 RStudio 不支持 Fcitx!官方不作为,那只好自己动手了。 首先尝试了编译 fcitx-qt5,失败。不行,我要死磕这个问题认怂了,用 Ibus 去了。把输入法设置成 Ibus 之后,用了一段时间;感觉真是难用,还没有云拼音,突然十分怀念 Fcitx5。于是我启动了 Fcitx5,发现它可以和 Ibus 共存,真是不可思议。又可以在 RStudio 里用 Fcitx5了。 下面是设置方法: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 # 安装 Ibus 输入法,将它设置为默认的输入法 sudo apt install ibus im-config -n ibus # 安装 Fctix5 sudo apt install \ fcitx5 \ fcitx5-pinyin \ fcitx5-chinese-addons \ fcitx5-frontend-gtk2 \ fcitx5-frontend-gtk3 \ fcitx5-frontend-qt5 \ kde-config-fcitx5 \ fcitx5-module-ibus # 开机启动 Fcitx5 cp /usr/share/applications/fcitx5.desktop ~/.config/autostart/ # 设置 Fcitx5(如果已经设置过了就跳过这一步) fcitx5-configtool # 如果有缺失的包就先添加下面的 PPA: # sudo add-apt-repository ppa:hosxy/fcitx5 这个方法有个坏处:Fcitx5 在某些软件中显示的位置不正确。 俗话说,如果解决不了问题,就把提出问题的人解决掉。软件亦是如此,这个软件有问题,就换另一个咯。你可以用 RStudio Server,它是用浏览器访问的,Chrome 和 Firefox 都支持 Fcitx 5。如果你还是搞不定,那可以抛弃 RStudio,改用 Visual Studio Code。VS Code 也是支持 R 语言的。 延伸阅读 真正的解决方法:通过编译 fcitx-qt5 来让 RStudio 支持 Fcitx5 RStudio 中无法使用 Fcitx 的报告

2020/11/1
articleCard.readMore

在 Ubuntu 编译 GoldenDict

2024年8月14日更新 # 写这篇文章的初衷是 GoldenDict 没有停止开发但又很少发布新版,最近一次还是一年前(2023年5月31号)。现在推荐大家使用更新和发布频繁的 Goldendict-ng。Goldendict-ng 已被收录于 Debian、Ubuntu、Fedora、OpenSUSE 等 Linux 发行版,用 flatpak 安装也方便。 如果你点进来就是想编译 GoldenDict,请看 Goldendict 的文档,下面的内容可能已过时。 # 测试于 Ubuntu 21.04。 1 2 3 4 5 6 7 8 sudo apt-get update sudo apt-get install git pkg-config build-essential qt5-qmake \ libvorbis-dev zlib1g-dev libhunspell-dev x11proto-record-dev \ qtdeclarative5-dev libxtst-dev liblzo2-dev libbz2-dev \ libao-dev libavutil-dev libavformat-dev libtiff5-dev libeb16-dev \ libqt5webkit5-dev libqt5svg5-dev libqt5x11extras5-dev qttools5-dev \ qttools5-dev-tools qtmultimedia5-dev libqt5multimedia5-plugins \ libopencc-dev liblzma-dev libzstd-dev # 1 2 3 4 5 6 7 8 9 10 11 12 # 卸载源里面的 GoldenDict sudo apt remove goldendict # 克隆源代码 git clone https://github.com/goldendict/goldendict.git # 编译 cd goldendict qmake "CONFIG+=chinese_conversion_support" "CONFIG+=zim_support" make # 安装 sudo make install # 卸载 # sudo make uninstall 实际上不执行 make install 安装 GoldenDict 也可以用,运行编译好的 GoldenDict 就可以了。 1 2 chmod +x ./goldendict # 增加可执行权限 ./goldendict # 运行

2020/10/2
articleCard.readMore