命令行工具评分准则

概览

本文档适用于命令行界面 (CLI) 工具。图形界面 (GUI) 不在讨论范围内。

在为 Fuchsia 开发工具时,可以使用特定的功能和样式来实现一致性。本文档详细介绍了这些要求。

目标是让 Fuchsia 开发者工具保持一致和外观,以便开发者了解预期结果。他们可以轻松地了解如何完成常见任务,并且可以通过明确的途径探索更罕见的工具。

导视

开发者为 Fuchsia 编写软件的体验将影响他们对平台编写软件的一般感受,我们的工具是这种体验的重要组成部分。提供的工具不一致(相互不一致)会导致开发者体验不佳。

本指南提供了 Fuchsia 工具必须遵循的评分准则。

印度尼西亚

某些版块会使用“IDK”标识名,就像这个一样。这些详细说明了适用于 Fuchsia 集成商开发套件发行版所含工具的具体规则。

注意事项

在开始创建新工具之前,请考虑以下因素,以确定该工具是否适用于 Fuchsia 或 Fuchsia SDK。

印度尼西亚

IDK 工具在某种程度上是仅适用于 Fuchsia。广泛可用的通用工具不应包含在 Fuchsia 中,也不会包含在 Fuchsia IDK 中。例如,用于验证通用 JSON 文件的工具就不是很好的补充。但是,可以使用 JSON 格式的 Fuchsia .cml 文件验证工具。

ffx

ffx 是 Fuchsia 的统一 CLI 工具平台,用于托管到目标交互。它提供基于子命令的逻辑分组,映射到高级 Fuchsia 工作流。此外,它还提供了一个插件框架,以允许贡献者扩展 ffx 命令 Surface。ffx 作为 Fuchsia IDK 的一部分进行分发。

受众群体

工具可能用于不同的开发任务。在一个大型团队中,这些角色可能是独立的人员。部分类别包括:

  • 组件开发
  • 驱动程序开发 (DDK)
  • Fuchsia 开发 (SDK)
  • 构建集成(GN 等)
  • 质量保证 (QA)
  • 系统集成商(例如设备端网络工具)
  • 发布(从开发主机到服务器)
  • 部署(从服务器到客户)

考虑哪些用户可能会使用工具并满足受众群体的需求。

工具可能会有不同的集成预期。例如,进行组件开发的开发者可能希望工具能够与其集成开发环境 (IDE) 集成,而构建集成工具可以从脚本调用。

最好将相关命令放在常用工具(例如 ffx)下。例如,gitffxfx 可在一个面向用户的命令下提供多个功能(或“子工具”)。这有助于鼓励团队采用共享的工作流,并提供单点发现结果。

首选子命令而非多个工具。例如,不要创建名称带有连字符的工具,如 package-createpackage-publish,而应创建一个接受创建和发布子命令的 package 命令。

确保工具下的命令数量有条理且合理。也就是说,应避免向工具添加不相关的命令,并在帮助和文档中合理组织命令。

工作范围

命令行工具可分为两组:简单的单一用途工具,以及功能性更强的大型工具。创建符合人体工学用途的工具。简单的工具应该可以快速启动,而较复杂的工具则会倾向于功能更强大的工具。

较大的工具将包含用户(开发者)级别的整个任务。避免打造能够完成一小步的工具,而应打造能够执行完整任务的工具。

例如,当:

  • 开发 C++ 应用:运行预处理器、运行编译器、运行链接器,以及启动构建的可执行文件。
  • 处理单元测试:构建测试并运行正在进行的测试
  • 开发 mod:编译代码、将代码和资源移至设备、启动 mod(或热重载)

倾向于使用能够默认完成所有所需步骤,但允许高级用户执行部分步骤的工具(例如,传递参数以要求 C++ 编译器仅运行预处理器)。

印度尼西亚

对于开发环境集成商和 EngProd 团队,使用不同的工具。 build 集成商将学习每一个环节并将其整合在一起,形成一个有效的系统。

ffx

ffx 引入了许多子分组和相关的子命令。一般来说,对于主机以互动、系统集成和发布等类别中的工具,建议扩展现有的 ffx 服务,而不是新的独立工具。这可以通过其他标志、选项或子命令扩展 ffx 来利用共享的代码和功能。如需了解注意事项和其他详细信息,请参阅 ffx 开发概览

共享常用功能

如果多个工具都需要某个任务的一小部分,那么复制该代码是没有意义的。不妨考虑创建一个小型支持工具或创建一个库来共享代码。

制作一个执行任务一个步骤的小型工具可以促进代码重复使用。如果预计用户不会单独运行此小型工具,请将支持工具放置在未添加到 $PATH 的目录中。也就是说,避免不必要地污染环境路径。

最好提供一个库来共享代码,这样就不需要子进程。

实现

以下是关于创建工具的一些具体指南。我们将介绍以哪种语言编写该工具、以哪种语言使用等等。

ffx

ffx 遵循下述评分准则和惯例,并为概述的建议提供参考实现。

命名

以下内容适用于二进制文件、工具、子命令和长参数标志的名称。

使用美国英语知名的术语或名词作为名称。知名名词包括主题中常用的名词或整个子系统的名称。如果某个名称没有出现在文档中,则很可能不是为人所知。如果它未出现在任何实现中,则肯定不是为人熟知。

US-ASCII 字符集中只能使用小写字母 (a-z) 和连字符。一个连字符 (-) 用于分隔名称中的字词。平台所需的扩展程序除外(例如 .exe)。

使用三个以上的字符为 CLI 工具命名。确保短文件名可用于用户快捷方式(别名)。如果您认为某个工具应该有一个非常简称,请向 Fuchsia API Council 批准。

请谨记上述要点:

  • 最好使用整个字词,而不是缩写。
  • 最好使用较短的名称,因为预计用户会经常输入该名称。对于不经常输入的名称,请偏向于使用更明确的名称。
  • 首选单个字词而非多个字词
  • 优先使用子命令,而不是多个带连字符的工具(例如避免使用 foo-startfoo-stopfoo-reset;而是使用接受 start|stop|reset 命令的 foo)。
  • 尽量使其他类似命令或子系统的对称(尤其是动词),除非这种比喻引入了损坏的隐喻。

编程语言

工具可以使用 C++、Rust 和 Go 编写。为清楚起见,特此说明:Bash、Python、Perl、JavaScript 和 Dart(请参阅下面的例外情况)。

C++、Rust 和 Go 没有首选语言。这些语言之间的选择取决于该工具的作者。

印度尼西亚

如果作为 Fuchsia IDK 集成的 SDK 包含特定语言(例如 Dart),该语言可用于随该 SDK 分发的工具。也就是说,请勿在 SDK 中添加不会包含 Dart 运行时的 Dart 工具,但如果该工具已存在,也没有关系。

风格指南

请遵循正在开发的 Fuchsia 语言和区域对应的样式指南。例如,如果该工具包含在 Zircon 中并以 C++ 编写,请在 Zircon 中使用 C++ 的样式指南。具体而言,应避免为工具创建单独的样式指南。

尽量减少运行时链接依赖项(改为静态链接依赖项)。在 Linux 上,可以针对 glibc 库套件(libm 等)进行运行时链接;不允许使用其他运行时链接依赖项。

从源代码构建

请注意,一些开发者希望使用源代码构建工具。使用与平台源代码树中的代码相同的 build 和依赖项结构。不要为构建工具构建单独的系统。

托管平台

请留意工具会变得多么耗费资源,以及工具预期会在哪些操作系统上运行。

在各种硬件上运行

开发者机器可能具有几个 CPU 核心和中等大小的 RAM,也可能是数十个 CPU 核心和大量 RAM。不要假设主机非常强大,也不要假设服务器集群可用于分流工作。

支持的操作系统

本部分旨在方便读者阅读。本文档并非所支持平台的具体内容。

我们目前支持

  • 基于 Debian 的 Linux 发行版(其他 Linux 发行版也可以使用,但不受官方支持)
  • macOS(在 x86 上,M1 目前尚未正式支持)

为开发者编写的工具必须在这些平台上运行。还有其他平台需要考虑,虽然目前这些平台并不是必需的,但最好注意下面所列的平台。

您构建的工具应使其易于移植到以下平台:

  • Fuchsia(自主托管)
  • Windows

此列表并不详尽,我们可能支持其他列表。

不区分大小写的文件系统

文件路径中不区分大小写。例如,不要认为 src/BUILDsrc/build 是不同的文件。相反,切勿依赖于不区分大小写,因为有些平台区分大小写。

使用非英语语言区域的开发主机

对于非英语开发者来说,需要考虑以下几个方面:

  • 工具本身是否可以本地化
  • 工具文档是否可以本地化
  • 工具是否可以处理路径名称和包含非 ASCII 的数据
  • 工具是否可以在非英语操作系统上正常运行

相关工具以美式英语提供。不需要对工具进行本地化。(将来可能会发生变化。)

工具的文档将支持非 ASCII 字符。HTML 和 Markdown 均可支持 Unicode (UTF-8) 字符,因此它们都是理想的文档选择。并非必须进行翻译,只需考虑可能性即可。

对于包含二进制序列和空格的文件路径,工具将正常运行。请使用库来处理文件路径,而不是将路径处理为字符串。(例如 path.Join in Go。)

工具将在非英语平台(例如日语或法语)上正常运行。 这意味着可以不损坏二进制(例如 UTF-8)数据。例如,不要假设文本文件只有 ASCII 字符。

执行

在运行时(或执行时)考虑工具的行为方式。

针对不需要的工作进行优化

在适当情况下(例如使用构建工具),如果没有工作要做,请快速退出工具。如果可能,不妨向调用方提供依赖项相关信息,以便调用方能够准确地确定是否需要调用该工具,以便更进一步。

命令行参数

有三种类型的命令行参数:

  • 完全匹配的文字
  • 实参
  • 选项(例如开关和按键)

完全匹配的文字

确切文本按原样放置在命令行中。一段确切的文字可能是必填字段,也可能是选填内容。只有在需要消除歧义(即正确解析其他参数)时,才应该解析确切的文本参数。例如,如果 copy 命令接受了多个来源和目的地参数,则可以使用精确的文本参数来明确哪一个参数:copy a b c 可能不明确;而 copy a to b c 可能表示“a”被复制到了两个目的地。

参数

实参就像函数参数或用于插入数据的槽。通常,它们的顺序很重要。在示例 copy <from> <destination> 中,<from><destination> 都是有序参数。如果单个逻辑参数重复出现顺序,则顺序可能无关紧要。例如,请移除 <files>...,这样工具可能会按任意顺序处理 <files>

选项

有些参数称为选项。开关和键控(键值对)都是选项。选项往往会修改工具的行为或工具处理参数参数的方式。选项由短划线前缀字母或单词组成。

选项必须以一个(“-”)或两个(“--”)短划线开头,后跟字母数字标签。对于单个短划线,标签的长度必须为 1。如果标签长度不少于 2 个,则必须使用两个短划线。 例如:-v--help 正确;-help 无效。

对于包含多个字词的选项名称(例如“foo bar”),您必须在字词之间使用英文短划线(“-”)。例如,“foo bar”会变为 --foo-bar

所有选项都必须包含 (--) 选项。提供单字符简写 (-) 是可选操作。例如,您可以仅提供 --output 或同时提供 -o--output,但不能只提供 -o 选项而不提供长选项。

不要创建数字选项,如 -1-2。例如,不要让 -1 表示执行一次某项操作,可以添加一个 --once 选项。如果需要数值,请创建键控选项,例如 --repeat <number>

一个 (-) 或两个 (--) 短划线本身属于特殊情况,不能用作按键或开关。

开关

有开关意味着它所代表的功能处于“开启”状态,没有该开关意味着它“关闭”。将默认设置切换为“关闭”。与键控选项不同,开关不接受值。例如,-v 是一种常见的 switch,这意味着它很详细;它不接受值,因此可以切换,而不是键控值。

必须记录所有开关(不允许使用隐藏开关)。

不允许同时运行多个开关。例如,-xzf-vv,它们必须分开:“-x -z -f”或“-v -v”。

键控选项

键控选项由一个键和一个值组成。键在语法上与开关类似,不同之处在于键控选项需要键的值。例如,-o <my_output_file> 的键为“-o”,值为“my_output_file”。

请勿使用等号(或类似标点符号)来分隔键和值。 例如,请勿执行 -o=<my_output_file>

请注意一种罕见情况:避免创建可选键(值显示时不带其键)或可选值(键显示时不带其值)。将键值对视为可选但不可分割的说法更为明晰。即,如果键存在,必须提供值,反之亦然。请考虑创建一个参数,而不是带有可选键的键控选项。例如,不传递 [<config_file>] 表示不使用配置文件,而是使用“do-something [--config <config_file>|--no-config]”,其中传递 --no-config 表示不加载配置文件,而不是“do-something [--config [<config_file>]]”。

互斥选项

某些选项与其他选项并无意义。我们将这些选项称为互斥。

传递互斥选项会被视为用户错误。当发生这种情况时,该工具将执行以下操作之一:

  • 编写一条说明问题的错误消息,并使用非零结果代码退出;不执行任何操作(即数据未因调用而更改)。这是预期的处理,因此无需其他文档或备注。
  • 使某个选项的优先级高于另一个选项。例如“passing -z will override -y”。在这种情况下,处理会记录在 --help 输出中。
  • 也可以采用其他处理方式(即最先或后一种优先,或采用其他方式),但不建议这样做。在这种情况下,处理将记录在“说明”“选项”“备注”中;不过,“See Notes”可以在“说明”和“选项”中使用,完整说明请参阅 Notes
分组选项

没有具体的语法可以指明,启用一个选项也会影响另一个选项。当某个选项暗示启用或停用另一个选项时,请在“选项”中进行指定。例如,“passing -e implies -f”表示,如果启用了 -e,系统会启用 -f,就像在命令行中传递它一样(无论是否显式传递了 -f)。隐含值的冗余传递不会产生任何不良后果(而非错误)。

选项分隔符

两个短划线(“--”)单独表示参数选项的结尾。所有后续值都将按原样提供给该工具。例如,对于“Usage: foo [-a] <file>”,命令行“foo -- -a”可能会将 -a 解释为文件名,而不是开关。此外,“foo -a -- -a”会启用开关 -a(第一个 -a,在 -- 之前),并传递字面量文本 -a(第二个 -a)。

重复选项

重复开关可用于进一步强调(强调程度的意义由工具决定,此处的说明故意含糊不清)。一个常见的示例是,通过传递更多 -v 开关来提高详细程度。

可以使用重复的键控选项将多个值传递给同一命令。这样做通常是为了避免多次调用同一命令。接受重复选项的常见命令包括 cprmcat。必须格外小心,确保重复的命令清晰明确。例如,cp 始终会将最后一个参数解释为目的地;如果 cp 接受了多个来源和目的地参数,则解析可能会含糊不清或不明确。

标准输入别名

在 Fuchsia 工具中,单个短划线 (-) 不会解释为 stdin 的别名。使用管道将数据定向到 stdin,或使用 /dev/stdin 作为 stdin 的别名。(注意:/dev/stdin 不适用于 Fuchsia 或 Windows)。

单划线

单独的短横(“-”)会留待日后使用。

子命令

工具可以包含接受独立命令行参数的子命令。(类似于 git 工具)。子命令不以任何短划线开头。例如,在 fx build 中,build 参数是一个子命令。

如果某个工具有许多子命令,则它还应包含一个 help 子命令,用于显示有关其他子命令的帮助。例如,“fx help build”将为 build 子命令提供帮助。

子命令可能有自己的参数,并且主工具不会处理这些参数。工具名称和子命令之间的参数由该工具处理,子命令之后的参数由子命令处理。例如,在 fx -a build -b 中,-afx 工具的参数,而 -b 参数由 build 子命令处理。

常见功能

命令行工具应支持一些常见的开关:

  • --help
  • --quiet
  • --verbose
  • --version

互动帮助 (--help)

在这种情况下,工具必须接受 --help 开关,并向命令行提供使用情况信息。如需了解帮助文本的布局和语法,请参阅 CLI 工具帮助要求

显示帮助时,工具不得执行其他工作(即产生副作用)。

使用一个可以解析参数并提供来自同一来源的帮助信息的库。这样做可以使两者保持同步。也就是说,避免将命令行帮助内容编写成独立的文本段落。

确保互动式帮助内容简洁明了。为熟练的读者(即希望获得工具使用提醒的人,或熟悉阅读互动帮助内容的开发者)做好计划。对于新手,请提供一条说明,让他们参阅 Markdown 文档。

提供用于生成机器可解析输出的选项。

详细程度(--安静和 --详细)

--quiet--verbose 开关可减少或增加向用户的信息输出。它们的实现是可选的,但所有工具都接受它们作为参数,并且不得将这些术语用于其他目的,例如不要使用 --quiet 关闭音频输出(使用 --silence--volume 0 或其他一些同义词)。

交互式版本 (--version)

工具必须接受 --version 开关,并指明在这种情况下用于构建工具的代码。布局和语法未指定,但版本将包含某种版本号。

在报告其版本时,该工具不得执行其他工作(具有副作用)。

日志记录

日志记录与正常输出不同。日志记录的目标对象通常是尝试调试问题的工具开发者或高级用户。在特殊情况下(例如,当请求 --verbose 输出时),日志记录可能会转到 stdout。

来自多个线程的日志记录不会在一行内交错字词,即输出的最小单位是全文行。每行的前缀都表示该行的严重级别。严重级别为以下之一:detail、info、warning、error、fatal。

指标

每个工具都必须提交隐私权设计文档 (PDD) 才能收集使用情况指标。

指标对于推动质量和业务决策至关重要。我们希望通过指标回答的问题包括:

  • 我们的用户使用的是哪种操作系统?让我们知道如何针对不同的平台 确定工作的优先级
  • 他们使用了哪些工具?- 让我们知道如何确定投资的优先级,以及了解当前正在使用哪些工作流,以便确定投资优先级或找出不足之处
  • 他们使用工具的频率如何?- 让我们知道如何确定各项投资的优先级,以及了解当前正在使用哪些工作流,以便确定投资优先级或找出不足之处
  • 我们的工具在野外会崩溃吗?频率让我们知道如何确定工具维护的优先顺序
  • 如何使用工具?- 假设一个工具可以执行一项或多项操作,我们将学习如何确定在工具特定工作流中的投资优先顺序

您必须谨慎选择所收集指标的类型和内容。我们会执行 Google 标准的 PDD 审核流程,确保遵守 Google 的做法和政策。工具必须先获得批准,然后才能收集哪些指标,然后才能收集。

配置和环境

工具通常需要了解其正在运行的上下文。我们来看看应如何收集或存储该上下文。

阅读信息

工具不应尝试直接从环境中收集或直观地了解设置或其他状态。附加目标的 IP 地址、build 产品的输出目录或用于写入临时文件的目录等信息将从平台无关来源收集。将执行平台专用工作的代码分离出来可让工具在不同的平台之间保持可移植性。

在可行的情况下,应以主机用户熟悉的方式存储配置信息(例如,在 Windows 上,使用注册表)。工具应从 SDK 文件或平台专用工具中收集信息,这些工具封装了从 Windows 注册表、Linux 环境或 Mac 设置读取数据的工作。

工具也将公正地面向任何构建系统或环境。可以访问通用文件,例如 build 输入依赖项文件。

书写信息

工具不会修改配置或环境设置,除非工具明显以修改环境的预期部分为目的。

如果修改工具常规范围之外的环境可能会对用户有所帮助,则该工具可能会在获得用户明确许可后这样做。

执行成功和失败

退出时,命令行工具会返回 [0..127] 范围内的整数值。零表示成功(没有错误),1-127 表示各种错误形式。值 1 表示一般错误。用户必须记录除 0 和 1 以外的任何其他值。

通过 Grace 取得成功

如果未遇到错误,则返回结果代码零。

避免在成功时产生不必要的输出。不输出“成功”(除非用户要求提供详细输出)。

如有任何不清楚之处,请停止

如果该工具遇到不明确的情况或可能损坏数据,请勿继续操作。例如,如果让您要删除的目录的路径返回为“/”,则在尝试获取该配置信息时可能出错,请避免“不断升级”并移除“/”下的所有内容。

不要默默失败

工具必须通过返回非零错误代码来清楚地表明失败。在适当情况下(如果对该工具有意义或者用户明确要求提供详细输出),可以输出一条错误消息,说明哪里出了问题。

提供失败方向

当工具执行失败时,请明确错误是由于输入错误、缺少依赖项还是工具中的 bug 导致。使错误报告易于理解且可作为行动依据。

如果错误源于错误输入

  1. 如果用户向该工具提供了错误数据,请提供错误的背景信息,并引导用户修正输入,例如,输出发生输入错误的输入文件(以及行号,如果适合输入)。
    • 首选使用以下格式的输出(以便于正则表达式使用):file_name:line:column:description。这是许多工具常用的格式。也可以接受其他格式,但应尽量使用人类和工具都能轻松解析的格式。
  2. 提供更多信息参考。如果提供了相关文档,请提供该工具的一般文档链接或有关具体错误的文档的链接。如果工具能够提供更多详细信息,请进行描述(例如,gn 如何说明如何运行该工具以获取更多帮助)。

如果错误因依赖项缺失所致

  1. 请注意,错误是由缺少依赖项导致的。如果这不是问题,请勿让用户尝试调试其输入数据。
  2. 提供有关如何满足依赖关系的说明。可以是要运行的示例命令 (apt-get install foo),也可以是指向进一步说明的链接 (see: http:example.com/how-to-install-foo)。

如果错误来自工具中的意外状态(即 bug)

  1. 对不起。说明工具进入了非预期状态。不要让用户尝试猜测其输入数据是不良还是缺少依赖项。
  2. 建议邮寄名单或论坛以获取帮助。帮助用户了解 bug 是否已在下一个工具版本中得到修复;或者有人找到了解决方法。
  3. 邀请用户输入 bug 报告,并尽可能简化输入步骤。 提供一个指向 bug 数据库的链接,其中已预填充了工具和平台信息。

包含测试

工具必须包含可保证其正确行为的测试。每个工具都应包含单元测试和集成测试。测试将在 Fuchsia 持续集成环境中运行。

印度尼西亚

从 Fuchsia build(pm 等)导入的 IDK 工具具有在 Fuchsia 持续集成环境中运行的测试尤为重要,因为 IDK 聊天机器人目前不能阻止破坏性更改。

ffx ffx 平台提供了一个框架,用于引入在 Fuchsia 持续集成中自动运行的测试。贡献者可以在 ffx 源代码中查看插件测试和端到端自测的示例。

文档

Markdown 文档是添加更详细的用法示例和说明的合适位置。

印度尼西亚

IDK 中包含的所有旨在由最终用户直接执行的工具都必须具有相应的 Markdown 文档文件。

用户互动与程序化互动

工具可以由真人用户交互运行,也可以通过脚本(或其他工具)以编程方式运行。

虽然每个工具如果能够收集到合理的判断会默认进入交互模式或非交互模式,但它们还必须接受在给定模式下运行的显式指令(例如,允许用户执行编程界面,即使他们正在交互式 shell 中运行)。

标准

对于通常不具有互动性的工具,请避免请求用户输入,例如 Readline 或 Linenoise。不要突然显示出意外的提示来向用户提问。

对于交互式工具(例如 zxdb),会提示用户输入。

标准输出

在 stdout 上向用户发送输出时,请使用正确的拼写和语法,并避免使用不常见的缩写。如果使用不常见的缩写,请确保术语表中含有相应条目。

尝试检查终端的输出,例如查看用户是否在终端或者接收方是否为节目。

ANSI 颜色

允许使用颜色,但需要注意以下事项:

  • 抑制颜色:
    • 如有可能,请检查终端是否支持颜色,如果不支持,则禁止颜色输出。
    • 始终允许用户手动抑制颜色输出,例如使用 --no-color 标志和/或设置 NO_COLOR 环境变量 (no-color.org)。
  • 使用颜色时,请务必针对可能无法看到完整颜色(例如色盲)的读者使用鲜明的颜色。
    • 实现此目的的最佳方法是坚持使用标准的 8/16 颜色。与 256 种颜色不同,用户可以轻松重新映射这些颜色。
  • 切勿仅依靠颜色来传达信息。仅将颜色用作增强效果。无需看到颜色即可正确解读输出。

斯特尔

使用 stderr 报告无效操作(诊断输出),例如工具行为异常。如果工具的目的是报告问题(例如工具未失败的 linter),请将结果输出到 stdout 而不是 stderr。

如需详细了解如何报告错误,请参阅“成功”和“失败”。

全屏

避免创建全屏终端应用。请为此类工具使用 GUI 应用。

非互动(程序化)

在合理的范围内,添加程序化接口,以便实现自动化。

如果该网域已有协议,请尝试效仿(或有充分的理由不遵循)。否则,请考虑使用清单或 JSON 文件作为机器输入。

IDE(半程序化)

允许集成开发环境使用工具。这通常涉及接受输入清单并生成清单。

互动(用户)

对于许多工具而言,在工具运行时与用户互动并不常见。有些工具可能会以交互方式作为选项运行,例如 rm -i 会在每次移除前提示用户。

状态文件

状态文件会对信息进行编码,以便在工具之间共享数据。状态文件的示例包括 PID 文件和锁定文件。

避免使用 PID 文件包含正在运行的可执行文件的进程 ID。

避免使用锁定文件来管理资源访问的相互排除(即互斥)。