WSL 配置指北:打造 Windows 最强命令行

在两年前的八月,Microsoft 正式发布了 Windows 10 Anniversary Update 周年更新(它还有着 RS1,Version 1607,Build 14393 等一大堆别名)。其中最让包括我在内的众多开发者感到兴奋的特性之一,就是 WSL(Windows Subsystem for Linux,当时还叫 Bash on Ubuntu on Windows)的正式加入。

在 Windows 上原生运行 Linux 可执行文件,牛逼疯了!

然而 Bug10 也不是浪得虚名,原本只提供给 Insider 的 WSL 在正式发布后依然问题多多(不仅 zsh、tmux 等工具无法使用,网络相关的操作更是一概欠奉,还有各种各样 奇妙的 BUG),基本没有可用性,我在尝鲜了一段时间后也不得不重回 Cygwin 的怀抱。不过好消息是,在之后的更新中,这些 BUG 都已被逐一消灭

经过了两年的发展,WSL 已经足够成熟,我也是时候完成这篇一咕再咕的博文了。

(开学在即,仓促成文,如有谬误,还请指正。)

get-wsl

阅读全文→

添加 Notepad++ 至右键菜单的几种方法

作为一名即将开学的计算机系 准大学生,笔记本电脑总归是要有一台的。于是上星期我入手了 小米游戏本顶配版(i7-8750H + 16G + GTX 1066),最近正在重新折腾开发环境,这篇文章要解决的问题也是在此过程中出现的。

至于为什么要买小米的本子,主要是因为它的「游戏本性能 + 商务本外观」这一点正戳中我好球区。不过这几天使用下来,只能说缺点确实不少,有购买意愿的朋友需谨慎。在 Twitter 上搜索 小米游戏本 from:printempw 就能看到我发的吐槽简评,如果之后有时间的话也打算专门写篇评测(咕咕咕)。

回到正题。因为以前家里的电脑是全家共用的所以没什么,不过最近有了自己的电脑,我的软件洁癖就上来了:绿色版(便携软件,Portable Application)的绝不用安装版,国产软件一律扔沙盒运行。

看起来有点偏执,不过我就属于那种想把自己设备中的一切纳入可控范围内的人。Windows 在这点上就很讨厌,尤其是注册表的设计,比类 Unix 系统难管理了不是一点半点。在手机上也是一样,不能解锁 bootloader 的 Android 机器我绝对不会购买,AppOps、Magisk、存储重定向 等工具更是必备。虽然我也没偏执到「每条指令运行都需要我的许可」那种程度,不过至少,我的设备必须听我的话,我说什么不能做那就是不能做,你他娘的不能给我自作主张(比如 Windows 广受诟病的自动更新机制、某些臭名昭著的国产软件扫描用户硬盘等)。为什么?因为是我在用电脑,不是电脑用我。

好了言归正传(没错,本博客就是有在进入正题之前瞎扯一通的习惯)。

Notepad++ 是一款我很喜欢的文本编辑器,除了写代码和写文章外的一般文本编辑工作我都是使用它完成的,配置新电脑时自然不能少了它。我下载的是 Portable 便携版,不过也正因如此,原本在 Installer 中通过选项可以添加的 Edit with Notepad++ 右键菜单项也没有了(此操作需要写注册表)。

因为这个右键菜单还蛮好用的,所以我打算把它找回来。

npp-context-menu-demo

阅读全文→

博客迁移至 GitHub Pages

就在刚才,我把博客完全迁移到了 GitHub Pages 上。

为啥呢?简单来说,就是我懒得维护服务器了。

去年十月份,我为博客添加了 Travis CI 自动构建流程,发布新博文只需要把 Markdown 源码 push 至 GitHub 上的仓库,CI 会帮我自动完成后续的所有步骤,很适合我这种懒人。

在我的 CI 脚本中,博客构建完毕后会把构建结果 同时推送 至 GitHub Pages 和我自己的服务器。由于我之前一直是在自有服务器上部署的动态博客程序(WordPress、Ghost),一直用下来也没什么不妥,所以当时我也只是把 GitHub Pages 当成一个备胎,博客域名依然是解析到自有服务器上的。

但是最近我想了想,把博客部署在自己的服务器上,有几点不好:

首先是服务可用率。我是个穷屌,只有一台 DigitalOcean $5 的机器,既没有负载均衡,也没有冗余服务器。如果这台机器宕掉了,那博客就只能跟着下线,谁也访问不了。而且事实上我的服务器就有好几次莫名其妙出现过 Kernel Panic,收到监控报警后只能灰溜溜地去登录控制台重启服务器。

另外就是,我想在这个世界上留下点什么东西。如果博客放在我自己的服务器上的话,假如我出了啥三长两短、服务器久了没人管理,那我的博客很有可能就烟消云散了,多难过啊。

不过当然啦,要是那么在意这个的话,我就去用 Medium 这类写作平台,而不是自建独立博客了。我觉得 GitHub Pages 这类托管服务算是一个不错的平衡点,既保留了独立博客的风格,又不用特别去担心服务器的问题,自己只用操心内容就够了,挺不错的。

命令行界面 (CLI)、终端 (Terminal)、Shell、TTY,傻傻分不清楚?

诸君,好久不见。

为什么突然想写这样一篇文章呢?其实是因为在最近计划发布的一篇关于 WSL (Windows Subsystem for Linux) 的博文中,我打算对终端模拟器、Shell 的选择与配置进行一些说明。不过对于刚接触 Linux 或者刚接触命令行界面的同学,可能会有些难以理解它们之间的区别(事实上我当初也是这样)。

虽然这个话题已是老生常谈,搜索一下应该也能找到大把的相关文章。不过难得提到了这方面,就趁此机会把我的理解写下来,一来看看我是不是真正理解了,二来看看我能不能把它们之间的区别讲得更加简明易懂。

0. 太长不看 TL;DR

  • 命令行界面 (CLI) = 使用文本命令进行交互的用户界面
  • 终端 (Terminal) = TTY = 文本输入/输出环境
  • 控制台 (Console) = 一种特殊的终端
  • Shell = 命令行解释器,执行用户输入的命令并返回结果

1. 什么是命令行界面?

命令行界面,通俗来讲,就是你看过的那种满屏幕都是字符的界面。

阅读全文→

近况报告:我的高复生活

好久不见。

当你正在阅读这篇文章时,你应该很难想象,一位半年多没有写过博客的老鸽是以怎样复杂的心情打出这些文字的。由于我实在是太久没有正经写过文章了,对文字的感觉也未免生疏,所以这篇近况报告可能会写得像流水账一样又臭又长。你就把本文想象成是一位老年人博主重拾博客更新前的康复训练,以温暖的目光看下去吧。

我为什么这么久没写博客了?

为什么?因为忙啊,不然还能是为什么。(笑)

不过不得不承认,我这一年更新博客的频率确实是低到史无前例:2018 年到现在,我只发布过 2 篇博文,这个数据是 2017 年的十分之一。为什么呢?有看过我前几篇博文的朋友应该都知道,我在去年的高考中没有取得理想的成绩,在一番权衡后,我选择了高考复读这一条道路。

高考复读,也就是再读一年高三,再经历一次高考。

阅读全文→

如何将现有 git 仓库中的子目录分离为独立仓库并保留其提交历史

这几天想要把一个 git 仓库中已经存在的一个子文件夹独立成一个新的 git 仓库,并且保留之前关于此文件夹的所有提交历史。不过我对 git 并没有这么精通,只好上网搜索之。可能是因为我关键词抓得不准,搜了好一会儿才找到可行的方案,所以写篇博文记录一下,希望能帮到后来人。

另外,在 git 里这种掌控历史的感觉真棒(笑)

0x01 需求分析

我为什么会有如本文标题所述这样的需求呢?这是因为我之前把所有为 Blessing Skin 这个程序编写的插件源码都放在一个 git repo 中了,每个子文件夹中都是一个独立的插件(因为嫌麻烦所以一股脑给塞进一个仓库里了),并且对每个子文件夹中的代码的修改最后都是在这个统一仓库中提交的。该仓库差不多长这样:

$ tree
├── .git
├── avatar-api
├── config-generator
├── register-email-validation
│   ├── bootstrap.php
│   ├── package.json
│   └── src
├── report-texture
└── yggdrasil-api  <---【我想把这个独立为一个新 repo】
    ├── bootstrap.php
    ├── package.json
    ├── routes.php
    └── src

而我现在后悔了,想把其中的某个子目录抽离出来,把它变成一个新的 git 仓库,并且保留我之前所有在「原仓库」中关于这个子目录的「所有提交历史」。

其实这种需求还是挺常见的,举个栗子:

阅读全文→

Windows Update 出现错误 0x800703ed 可能的解决方法

HAIDOMO,这里是年终总结拖了两个月还没写完,上一篇博文发布于去年十月份的某鸽系博主 621sama DE-SU。其实 2018 年的第一篇博文原定应该是 2017 年的年度总结的,但是由于各种各样的原因,那篇文章到现在还没写完咕咕咕。

最近几天正好遇到了如标题所述的「Windows Update 自动更新时出现错误 0x800703ed」的状况,在网上搜索许久,最后历经千辛万苦才终于定位到了问题的根源。特此记录,希望能帮到后来人。

0x01 问题描述

虽然我现在已经没多少追 Windows Insider Perview 的热情了,不过最近巨硬推出的那个 Fluent Design 看起来还是挺赞的,就打算在 Windows Update 中升级到最新的 Insider Preview。虽然速度屌慢,但是还是成功地检查到了 Build 17093 的更新并且进入了「正在准备更新」这一阶段。谁曾想等进度跑到 100% 却出现了如下错误:

error 0x800703ed screenshot

这可太他妈的操蛋了。 阅读全文→

使用 Travis CI 自动部署 Hexo 博客

之前(六月份高考完后)我把博客引擎由 Ghost 换成了静态博客生成器 Hexo,并且只使用了自带的 Git Deployment 来手动部署生成好的静态博客文件到服务器上。虽然不像动态博客程序那样可以随时随地更新博客,但是想到马上就要上大学了,之后手头都会有电脑,所以更新博客也不算那么麻烦。

但是实在是人算不如天算,浙江这一届新高考改革是结结实实地把我坑了一把。二段线以上一段线未满这样中途半端的分数让人在填志愿时着实是犯难 —— 这次浙江几乎普遍出现「一段考生抢以往的二本中好学校,二段考生抢三本学校」这样神秘的情况。思来想去最后把心一横,决定去再读一年高四。后来全省高考录取情况出来后,也证实了我当时复读的决定也不是不合理的(譬如当时上了新浪微博热门话题的「浙江滑档大学」等)。

关于复读的话题就先放一放吧,毕竟现在的时间确实是有些紧,可能得等到寒假时才能好好地写一篇近况报告以及关于高四生活的事情了,非常遗憾。

回到正题,因为我输得透彻滚去读高四了,所以自然不可能每次都有配置完好的操作环境让我手动发博文 + 部署(虽然我也不见得有时间写什么博文)。在这样的前提条件下,一个 Hexo 博客的自动部署(持续集成)系统就显得非常有必要了。

0x01 需求分析

首先我们需要了解的是,我们到底希望实现一个怎样的系统?以下是我的设想:

  1. 更新博客文章内容后 commit 到 GitHub repo(也可以直接在 GitHub 网页上 commit);
  2. Travis CI 自动编译生成出新的静态博客文件;
  3. 自动部署至 GitHub Pages 和我自己的服务器。
阅读全文→

又是一种 Minecraft 外置登录解决方案:自行实现 Yggdrasil API

最近给 Blessing Skin 写了个插件,利用皮肤站本身的账号系统实现了 Yggdrasil API(就是 Mojang 的登录 API),然后配合 authlib-injector 这个项目将启动器(基于 Java 编写的支持正版登录的启动器都行)、Minecraft 游戏、Minecraft 服务端中的 Mojang Yggdrasil API 地址给替换成了自己实现的第三方 Yggdrasil API 地址(字节码替换),从而实现了与正版登录功能几乎完全相同的账户鉴权系统。

通俗地讲,就是我把 Mojang 的正版登录 API 给【劫持】成自己的啦,所以可以像登录正版那样直接用皮肤站的邮箱和密码登录游戏(还支持 Mojang 都不支持的多用户选择哦)。这种外置登录系统的实现应该可以说是比市面上的软件都要完善(毕竟可以直接利用 Minecraft 本身自带的鉴权模块),因此写一篇博文介绍一下这些实现之间的不同之处,顺带记录一下实现 Yggdrasil API 时踩到的坑,算是抛砖引玉了。

注意:本文不适合小白及问题解决能力弱的人群阅读。

感觉我明明好久没玩 MC 了,要玩也都是玩正版服务器,但是却一直在搞这些盗版服用的东西,我真是舍己为人造福大众普惠众生啊(不

一、服务器内置登录插件

相信维护过 Minecraft 服务器(当然,我这边说的是运行在离线模式下的服务器)的腐竹们或多或少都听说过 Authme、CrazyLogin 等登录插件的鼎鼎大名吧。由于这些服务器运作在离线模式(online-mode=false,即俗称的盗版模式)下,缺少 Mojang 官方账户认证系统的支持,所以必须使用这类插件来进行玩家认证(否则随便谁都可以冒名顶替别人了,换一个登录角色名就行)。

这类插件的工作原理就是在服务端维护一个数据表,表中每一条记录中存储了角色的「角色名」、「登录密码」、「注册时间」、「登录 IP 地址」等等信息,当玩家初次进入服务器时需要通过这些插件进行注册操作(e.g. /register 命令)并在表中插入一条记录,注册完毕后进入服务器则需要输入密码(e.g. /login <password> 命令)来认证。

其实这样的解决方案也没什么不好,而且现在 Authme 等登录插件在众多的服务器中都还是主流。但是,如果你的服务器已经发展到比较大型了,或许你就比较希望有这样一个东西:

阅读全文→

Laravel 动态添加 Artisan 命令的最佳实践

虽然 Laravel 官方文档提供的添加 Artisan Command 的方法是直接修改 app/Console/Kernel.php 文件并在 $commands 属性中注册要添加的 Artisan 命名的类名(Laravel 服务容器会自动解析),但是,如果我们出现需要「动态(运行时)添加 Artisan 命令」的需求的话,就会很容易吃瘪。因为,Laravel 的文档(当然,我说的是官网上的)几乎没有提到任何关于这方面的内容。

这也是我为什么总是吐槽 Laravel 文档有些地方很烂的原因 —— 很多时候你为了实现一个文档里没提到的功能,需要去翻半天 Laravel 的框架源码才能找到解决方法(我博客的 Laravel 标签 下已经有不少这样的踩坑文了)。虽然 Laravel 框架的源码很优雅,看着也不会难受,但是在一堆文件中跳来跳去寻找逻辑浪费脑细胞的行为还是能省则省吧 :(

这次要实现的功能是在运行时动态加载自定义的 Artisan Command(更详细一些的需求就是在皮肤站的一个插件中注册 Artisan 命令,Laravel 插件系统的实现可以参考我之前的 另一篇文章)。

TL;DR 太长不看

总之先上干货,毕竟不是所有人都喜欢听我废话一大堆后才拿到解决方案的。

Laravel 5.3 及以上:

Artisan::starting(function ($artisan) {
    // 传入类名字符串即可,会被服务容器自动解析
    $artisan->resolve('Example\FooCommand');
    // 批量添加
    $artisan->resolveCommands([
        'Example\FuckCommand',
        'Example\ShitCommand'
    ]);
    // 参数必须为 Symfony\Component\Console\Command\Command 的实例
    // 继承自 Illuminate\Console\Command 的类实例也可以
    $artisan->add($command);
});

Laravel 5.2:

Event::listen('Illuminate\Console\Events\ArtisanStarting', function ($event) {
    // 其他用法同上
    $event->artisan->resolve('Example\BarCommand');
});
阅读全文→