4

如何优雅地管理你的 shell 脚本?

 4 years ago
source link: http://chuquan.me/2021/04/05/how-to-manage-your-shell-scripts-gracefully/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

如何优雅地管理你的 shell 脚本?

发表于 2021-04-05

|

更新于 2021-04-05

| 分类于 Shell

几乎所有的程序员都或多或少接触过 shell 脚本,在 shell 脚本的使用过程中,我们会遇到一些痛点,比如:执行方式、使用方法等。

本文,我们将简要分析一下这些痛点,并最终给出一种优雅的解决方式。

一般我们执行脚本的方式主要分为两种:

  • 路径调用,如:./path/to/script.shsh ./path/to/script.sh
  • 全局调用,如:将 shell 脚本代码直接写入 ~/.zshrc 或使用 alias 指定具体的脚本路径,从而实现全局调用。

不过,这两种方式显然不够优雅,下面我们来具体分析一下。

绝大多数人都会采用这种方式来执行脚本。路径调用的优点是操作简单易懂;但是缺点也很明显——我们需要提前知道每个脚本在文件系统中的位置。

在交叉调用的场景下,通过相对路径很难进行操作,只能通过绝对路径来进行调用。比如:在 ~/chuquan/Develop/A/ 目录下调用 ~/chuquan/Github/B/script.sh 时,只能通过绝对路径进行调用。

为了解决路径调用的所存在的问题,有些人可能会采用以下几种方式来解决。

第一种方式是:将 shell 脚本的代码写入 shell 配置文件中,如: ~/.zshrc。比如,将下面的函数加到 ~/.zshrc 末尾,然后执行 source ~/.zshrc 或重启终端后,我们就能进行全局调用 chuquan 这段 shell 脚本。

# ~/.zshrc 的末尾
func chuquan() {
echo "Hello, CHUQUAN"
}


# 全局调用 chuquan
$ chuquan
Hello, CHUQUAN

上述方式的原理是:在终端启动时,系统会根据其所指定的 shell 加载对应的配置文件。如果默认 shell 是 zsh,那么会加载 ~/.zshrc 配置文件。我们在 ~/.zshrc 中写入 shell 函数会成为全局函数,从而实现 shell 脚本的全局调用。

这种方式的主要缺点在于:

  • ~/.zshrc 中不能存在同名的脚本函数,如果存在,后者会覆盖前者。
  • 如果脚本代码特别多,会导致 ~/.zshrc 文件变大,最终 shell 启动时加载 ~/.zshrc 的时间也会相应变长。

第二种方式是:使用 alias 针对每一个脚本及其绝对路径,定义一个别名。比如,通过 alias 命令为 ~/chuquan/hello.sh 指定一个别名 hello,从而实现全局调用。

$ alias hello=~/chuquan/hello.sh

这种方式可以解决第一种方式的缺点。当时它并不够优雅,如果脚本非常多,对应的别名也会非常多,对于用户而言,我们真的都能记住吗?

关于使用方法,我们经常会遇到这样的情况:当别人写了一个非常牛逼的脚本后,我们想要使用它时却并不清楚其确切的作用,甚至不知道它执行时需要哪些参数。在这种情况下,我们经常会与一些可以提升工作效率的脚本工具失之交臂。对此,最好的解决方式就是脚本的作者在脚本中给出使用提示、参数提示。

为了解决上述的问题,我写了一个基于 zsh 的脚本管理工具——NOX

NOX 主要有一下这些特点:

  • 系统调用:NOX 实现了一个唯一的主命令 nox,并将用户脚本的存放路径和脚本名称转换为子命令,从而实现全局调用。比如:通过 nox poker ace 命令来调用 scripts/poker/ace.sh 脚本。
  • 自动补全:如果说用户手动输入类似 nox poker ace 这样的命令会很费时,那么 NOX 也实现了一种优雅的解决方案——支持 Tab 自动补全。通过 Tab 自动补全,从而加速命令的索引和调用。
  • 帮助选项:为了解决用户不知道脚本如何使用的问题,NOX 提供的 nox system create 命令可以为开发者快速创建一个默认支持 --help(或 -h) 选项的脚本模板。脚本开发者只需要修改脚本模板中关于脚本使用用法的描述即可。
  • 调试模式:为了方便用户进行脚本调试,NOX 在脚本模板中默认支持了 --debug(或 -x)选项,可以轻松将脚本执行模式切换至调试模式。
  • 私有命令:NOX 可以作为一个开发团队的工具箱,同时为了支持私有命令,NOX 默认不会将以 _ 为前缀的目录或脚本名称加入 git 管理。

下图所示是一个通过 NOX 调用 scripts/poker/ace.sh 脚本的示例。示例中使用 nox poker ace --count 10 命令,期间结合 tab 自动补全进行快速索引,最终调用 scripts/poker/ace.sh 脚本,并传入脚本选项 --count 和参数 10

是不是很酷炫?

NOX 的本质是一个脚本管理工具,它的目标还是为脚本服务。为此,NOX 提供了 3 个内置的系统命令供用户进行使用。

创建目录/脚本

NOX 提供了 nox system create,该命令能够创建一个模板目录或模板脚本,具体使用选项进行区分。

  • nox system create --dir <dirname>:可以创建一个脚本目录,默认会在该目录下创建一个 .description 文件,用于描述该目录分类下的脚本的功能。
  • nox system create --script <script-name-without-suffix>:可以创建一个模板脚本,该脚本默认符合 NOX 开发规范,用户只需要修改对该脚本进行定制修改即可。

编译自动补全逻辑

自动补全功能的核心是一个描述自动补全逻辑的自动补全文件,对此,NOX 提供了一个命令 nox system build 以供编译生成对应的自动补全文件。该命令会生成一个 _nox 文件,并存放在 fpath/ 目录下。

当我们创建一个目录或脚本后,需要执行 nox system build 命令,从而生成一个新的自动补全文件。然后,我们需要执行 source ~/.zshrc 或重启终端以更新自动补全逻辑。

NOX 可用于团队协作,当其他开发者贡献了一些新的脚本后,我们可以通过执行 nox system update 来更新 NOX 仓库,从而享受最新的功能。

NOX 能够将自己编写的脚本转换成系统命令,这是一个非常酷炫的特点,此时的你想必也跃跃欲试。这里有一个简单的例子,详细介绍了如何开发一个符合 NOX 规范的脚本,详见 传送门

NOX 提供了一种优雅地管理 shell 脚本的解决方案,它将 shell 脚本转换成了系统命令,并提供了强大的自动补全功能。欢迎大家来安装、使用并提出修改意见~

  1. nox

Recommend

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK