命令行工具开发指南——入门篇
前言
命令行工具(Command Line,Cli)作为我们日常开发常用的辅助性工具,几乎遍布于各种操作中。根据使用目的的不同大致可以分为以下几类:
- 从模板中生成项目:比如使用
npm init从空模版创建一个新的 NodeJS 项目,使用composer create-project laravel/laravel example-app创建一个全新的 Laravel 项目(PHP 项目)等。 - 启用开发者服务模式:比如使用
python -m http.server 8000在 8000 端口开启一个临时 HTTP 服务器,使用bundle exec jekyll s在 4000 端口开启一个临时 Jekyll 服务器等。 - 特定功能交互:比如流行的 IP 信息查询工具 nali、磁盘空间利用率和空余空间查询工具 duf、快速磁盘使用分析工具 gdu 等。
其实任何编程语言都可以用来开发命令行工具,无论是常见的 Golang、Python、NodeJS、PHP、Java,还是 Rust、Ruby、C++、C 或者是古老的 Fortran 等。只是取决于所要实现的功能和具体的使用场景,开发者会采用合适的编程语言开发命令行工具。比如说,Linux 系统中包含了大量的命令行工具,基本上都是用 C 语言编写的,主要是因为 C 语言在 Linux 系统中的执行效率相对更高。对于一般高级编程语言,自带的包管理工具也是由自身高级编程语言编写的命令行工具。类似 Rust、Fortran 等编译型语言则需要通过编译生成二进制可执行文件后才能执行相应的任务。
二进制可执行文件是指源代码通过编译器编译成计算机可以直接识别的二进制码文件。二进制码文件是无法使用任何源码编辑器打开的,只能由操作系统调用执行或特别的二进制码查看器打开。一般来说,二进制可执行文件是很难跨越操作系统的,即针对不同的操作系统需要分别编译生成对应的二进制可执行文件。尤其是当有其他静态库或者动态链接库依赖时,二进制可执行文件甚至无法跨主机运行。 而源文件是可以在任何操作系统用源码编辑器打开的。大多时候商业公司为了保证源代码的商业版权,只会为用户提供应用的二进制可执行文件。(当然一般可能是包含图形用户界面的。)
为何命令行而非图形界面
命令行可以说是操作系统应用和编程语言编写应用最基本的形式,图形(用户)界面(Graphic User Interface,GUI)则是在源代码的基础上提供可视化的交互方式、通过键鼠操作来降低用户使用的门槛。这也是为什么 Windows 操作系统比 Linux 操作系统更加流行的原因之一。但是有的时候,界面也有可能会成为用户学习和使用的累赘。
简单界面 vs 复杂界面
就拿代码编辑器来说,我们所熟知的“宇宙第一编辑器” Visual Studio 几乎支持所有编程语言,尤其是对于构建 C# 项目来说可以半代码半可视化修改。尽管这在很大程度上降低了开发者使用成本,但是学习 Visual Studio 编辑器本身的成本却很高。(说句老实话,笔者从大学本科开始接触 Visual Studio 到现在都没怎么学会使用,😂只会最基本的功能而已。)而且,在普通笔记本电脑上使用 Visual Studio 编辑器运行大型项目时,CPU 和内存资源极大可能会被大量占用,打开一个浏览器页面可能也很艰难。
相比而言,同样由微软推出的 Visual Studio Code 则是简单界面的优秀代表。化繁为简,Visual Studio Code 本身仅支持最简单的功能:文件目录区、编辑区、终端区三部分布局,基本的代码高亮功能,插件功能,主题功能等。无论是 Python 开发者,还是 Golang 开发者,都能一打开直接上手,只是需要根据编程语言不同安装一些插件来提升开发效率而已。在系统占用资源方面,Visual Studio Code 比 Visual Studio 显著降低,尽管可能也会受安装插件的少量影响。当然有得也有舍,Visual Studio Code 中支持更多文件定义配置或命令行配置,对于没有学过 Linux 的用户可能会有点学习难度。
“一切皆文件”。任何系统、项目、工具都是由一系列的文件组成的,通过配置文件可以实现直接管理。
虽然这是 Linux 系统设计的哲学思想,但其实是所有操作系统设计的哲学思想,只是顶层封装的程度有所不同。Windows 系统也是“一切皆文件”的,不然那些编辑器的配置都存在哪里了呢。相比 Linux 和 MacOS 系统而言,Windows 系统的顶层封装程度最高,用户对于底层文件的直接管理非常少,尤其是对系统级别的配置管理只能通过图形界面交互完成。MacOS 系统则是介于两者之间,顶层封装程度虽然高但也提供对大部分系统级别配置的直接管理,即可以通过修改文件来实现管理。尽管依旧存在有些系统级别配置难以直接修改,比如说操作系统启动项。
更简单的命令行
界面在执行系列任务时一般需要多步操作,一顿点点点之后才能完成。当然如果图形界面和功能设计的比较合理的话,可能也只需要一步操作。当我们需要进行批量操作时,即使图形界面只需要一步操作,依旧需要一顿点点点。命令行则没有这种问题,只需要简单写个有循环的脚本即可循环调用命令行工具批量执行。
另外,命令行工具仅在执行时会占用系统资源,一旦完成即可完全释放。图形界面应用一般需要常驻后台,虽然优化得好的时候所占用的系统资源也可忽略不计,但是还是会有后台进程的。
尽管命令行工具极少会有显式的界面交互,但是也可以在终端提供非常丰富的命令行交互、功能解释、自动补全、自动建议等。用户使用起来一般没有太大问题,只需要调用子命令和参数即可实现操作。
命令行工具开发
设计标准和规范
命令行工具开发通常依据两个标准和规范进行:POSIX (Protable Operating System Interface,可移植操作系统接口) 标准和 GNU (GNU’s Not Unix) 项目。POSIX 标准是 IEEE 为维护操作系统间适配性而制定的一系列标准,其中一个标准定义了命令行程序的语法和语义。GNU 旨在创建与 Unix 兼容的自由软件,其中一个子项目 GNU Coreutils 提供了很多常用的命令行程序,比如 ls、cp 和 mv 等。据此为命令行程序建立了以下的设计标准和规范:
- 单字母标志 (single-letter flag) 以一个短横线
-开始,且可以合并使用:比如-d(全称--debug) 和-v(全称--version) 合并使用-dv来以调试模式输出命令行版本号。 - 长标志 (long flag) 以两个短横线
--开始,但无法合并使用:比如--debug或--version可以被命令行正常解析,但--debugversion...
剩余内容已隐藏