什么是命令行程序?
在本节课中,我们将讨论命令行程序是什么,并看一个示例。我们还将学习命令行参数。
一个命令行程序是在终端或控制台中运行的程序。它也可能向控制台输出一些内容。尽管 Unix 原则“静默是金”主张成功执行命令时不应有输出,但某些命令行程序可能是交互式的。当你运行它们时,它们会等待输入命令,并据此采取相应行动。然后它们会继续等待下一个操作,直到你显式退出为止。让我们来讨论一下命令行程序接受哪些类型的输入。
输入
程序可以读取标准输入流并以交互方式提示用户输入。然而,我们将重点关注以字符串形式使用命令行参数的程序。从语义上讲,这些参数可分为命令和子命令、标志(flags)以及程序参数。
大多数程序在不带任何参数的情况下运行时会有默认行为,如果未提供输入,则会显示用法信息。例如,git 会显示其帮助信息:
1git
命令
查看这个命令行 git stash。当你运行此命令时,它会把工作目录中尚未提交的更改暂存起来。因此,git 是我们的程序,stash 是 git 理解的一个命令。不过,stash 也有子命令。例如,git stash list 会列出所有暂存的内容。在这里,stash 是一个命令,而 list 是 stash 的子命令。命令和子命令通常是单词。将命令和子命令视为动词会很有帮助。
标志(Flags)
标志(有时称为选项或开关)用于修改命令的行为。标志通常具有长格式和短格式。短格式是以单个横杠开头的单字母前缀,如 -a;长格式是以双横杠开头的单词,如 --all。例如,要列出所有 git 分支,你可以使用命令行 git branch -a 或 git branch --all。
由于命令行参数没有统一标准,有时标志会充当子命令。例如,git branch -d <branch name> 表示删除名为 <branch name> 的分支,但有人可能会认为使用子命令 git branch delete 更自然。
参数
参数是命令所操作的内容。然而,有些命令不需要参数,比如 git status,它只是返回当前仓库的状态。在这种情况下,无需额外参数,但大多数命令都需要一些参数。例如,git add 命令会将文件或目录添加到暂存区,使其准备提交。
以下 shell 脚本创建了几个文件,在第 3 行添加它们,并检查状态。
1touch file-1 2touch file-2 3git add file-1 file-2 4git status
输出
命令行程序通常将其输出写入流。存在标准输出流和标准错误流,这些流可以被重定向到不同目标(如文件),以便区分成功结果与错误。
管道(Pipes)是 Unix 中的一种机制,多个程序被串联在一起,使得前一个程序的标准输出成为下一个程序的标准输入。另一方面,标准错误仍会输出到终端,除非被重定向。要实现程序之间的管道,只需在它们之间添加竖直管道符号(|)。
例如,我们可以将 ls 的输出通过管道传递给 wc,以统计当前目录中的条目数量:
1ls | wc -l
然而,如果我们向 ls 传递一个不存在的路径,它会产生错误,而 wc 将收不到任何内容。在这种情况下,管道的输出将是零,因为 wc 没收到任何输入,而 ls 的错误信息仍会被打印出来。
1ls no-such-path | wc -l
退出码
当程序退出时,它会返回一个整数退出码。这里,0 表示成功,非零表示失败。
其他形式的输出
输出和错误流是命令行程序的核心,但还有许多其他形式的输出。程序可以选择写入文件、发起网络调用、向连接到主机的设备发送命令,或调用其他程序。如果你是纯粹主义者,可能会认为这些是副作用而非输出,但重要的是要认识到命令行程序所能做的远不止简单的文本处理。特别是,git 本质上是关于管理文件的,其索引可以与远程服务器交互。其他很好的例子包括 ssh 和 aws CLI。
其他程序类型
正如你所见,命令行程序非常灵活,但通常具有相对丰富的命令词汇量。用户或其他程序调用它们来执行一个命令,然后退出。
其他程序通常是长时间运行的,因为服务器是一类程序,它们等待传入的请求或连接,处理请求,将响应返回给调用者,然后等待下一个请求(或下一段数据包)。Web 服务器是实现 HTTP 协议的服务器的良好示例。
具有图形用户界面的程序和游戏是另一类交互式程序,它们从键盘、鼠标或其他控制器获取输入,并以屏幕更新作为输出。这些程序通常包含一个主循环,并以高频率刷新显示,以提供流畅且高保真的用户体验。
测验
让我们以一个小测验结束本课……祝你愉快!
Quiz
命令行程序通常执行一个命令后退出