LOADING...

加载过慢请开启缓存(浏览器默认开启)

loading

为什么有 Seashell 2 和 Bashert

关联

缘起

早在 13 左右的时候,我就特别依赖于在容器运行 GUI 应用,从配置麻烦的 Lxc 到占用资源的 Docker,最终到 Lxd 和 Systemd-nspawn,其间需要写大量的 ShellScript 来使容器里的 GUI 能够正常在主机里的运行,如我会为 Firefox 浏览器和 Steam 游戏平台各写一个脚本,里面有相当一部分重复内容:

  • 容器维护(容器运行和初始化)
  • 发行版相关维护(包安装以及系统配置)
  • Device(如 GPU 等的)
  • Xorg(Socket 和 Xauth)
  • Audio
  • 环境变量
  • ……

虽然,ShellScript 本身可以 source,但是是非常难以项目化,这对于一个开发多年的人来说也是非常难以接受的,所以便有了我的第一次尝试:Seashell

Seashell 并没有太多“对于一个 ShellScript 库该如何写“去做深入思考,而是为了应用层面的实现去临时拼凑出的一盘杂碎,像对于导入其他脚本,临时有像 C/C++ 那样 include 的 idea,又冒出像 Java 那样 import 的 idea,加了太多草率实现的杂音,其中一部分还跟自己初衷有点违背,而且想兼容 zsh 和 bash,其实又大部分没法做到。

总之,对于没有深思过的 Seashell,我一直都想抛弃掉,奈何没时间和应用层面脚本一直都可以用,就一直搁置着。

重来

在没上班的日子里,玩也玩得够久了,于是久违的”项目化 ShellScript”就被提上日程,心想就折腾个 Seashell 2 吧。

重新实现的 Seashell 2,并不是跟之前一样,以应用来驱动库开发的,而是自己脑补库所需:

  • 核心库与应用脚本分开,于是单独有了 Bashert 这个应用脚本项目
  • 更加清晰的模块化和命名空间,语义更加一致
  • 尽量的无入侵性,对于无项目化的脚本基本没有迁移成本
  • 能标记最终脚本的样子,方便调试
  • 核心库提供更好的 Hooks,能以后更好拓展功能
  • 核心库提供生成应用脚本项目的脚手架
  • 核心库能在 zsh 和 bash 下工作,但是应用脚本的兼容交给脚本人
  • 提供返回值,而非 Shell 子能返回状态值
  • 能够将模块化的脚本打包成一个单一脚本,方便部署
  • 提供交互模式,输出模式和运行模式
  • ……

然后一步一步去落实这些规划的功能。确实在有规划之后,实现功能比当初那种一头扎进泥泞去四处打补丁要简单且科学得多。

应用

Seashell 2 作为一个可以项目化 ShellScript 的库,它应该是稳定的且独立于应用脚本项目。那么我们需要思考一个 ShellScript 项目化后,它的目录结构应该是怎么样的。理想情况下,我觉得核心库和应用库得有一致的结构,才能减轻心智负担,最简单的结构可能是:

.                         # 库的当前目录
├── bin/                  # 应用脚本入口
├── mod                   # 库的定义
├── src/                  # 模块代码实现
└── vendor/               # 第三方库

一致的结构,可以方便由 Seashell 2 去提供一个脚手架帮助创建生成,Bashert 项目就是在 Seashell 2 提供的 seashellist 脚手架工具去生成的。Bashert 是一个应用层面的库,正如其名字,里面写的都是 BashScript,而非通用的 ShellScript,日常生活和办公,都有太多重复性且可以划分所属的功能,是很适合项目化组织的,如:

  • 命令行解析
  • 容器管理
  • 虚拟机管理
  • 音频转换
  • 视频转换
  • 爬虫
  • 系统管理
  • ……

作为独立应用的 Bashert,除了功能实现和功能复用及功能使用,还能作为第三方的库被引用,最大化重复利用脚本。