Homebrew 与 Git 类似,支持外部命令。这让你可以创建新命令,像这样运行
brew mycommand --option1 --option3 <formula>
而不修改 Homebrew 的内部内容。
外部命令有两种类型:Ruby 命令和 shell 脚本。
在这两种情况下,命令文件都应该是可执行的(chmod +x
),并且位于 PATH
中的某个位置。
外部命令可以添加到 tap 中,以便于分发。有关更多详细信息,请参见下方。
作为 Ruby 命令实现的外部命令 extcmd
应命名为 brew-extcmd.rb
。通过对完整路径名执行 require
来执行该命令。由于该命令是 require
的,因此它可以完全访问 Homebrew “环境”,即任何内部命令都可以访问的所有全局变量和模块。小心使用 Homebrew 内部内容;它们可能会在任何时候不经警告而发生更改。
该命令可以使用状态代码 Kernel.exit
,如果需要的话;如果它没有显式退出,则 Homebrew 将返回 0
。
名为 extcmd
的命令的可执行脚本应命名为 brew-extcmd
。脚本本身可以使用任何合适的 shebang(#!
)行,因此外部脚本可以用 Bash、Ruby 甚至 Python 编写。与 Ruby 命令不同,此文件不得以特定于语言的后缀(.sh
或 .py
)结尾。此文件将通过 exec
运行,其中一些 Homebrew 变量被设置为环境变量,并传递任何其他命令行参数。
变量 | 说明 |
---|---|
HOMEBREW_CACHE |
Homebrew 将下载的 tarball 缓存到的位置,默认情况下为 ~/Library/Caches/Homebrew 。 |
HOMEBREW_PREFIX |
Homebrew 安装软件的位置。对于 macOS Intel,默认情况下为 /usr/local ,对于 Apple Silicon,为 /opt/homebrew ,对于 Linux,为 /home/linuxbrew/.linuxbrew 。 |
HOMEBREW_CELLAR |
Homebrew Cellar 的位置,其中对软件进行暂存。如果该目录存在,则此位置为 HOMEBREW_PREFIX/Cellar ,否则为 HOMEBREW_REPOSITORY/Cellar 。 |
HOMEBREW_LIBRARY_PATH |
包含 Homebrew 自有应用程序代码的目录。 |
自制软件存储库 |
Git 存储库目录(即 Homebrew 的 .git 目录所在位置)。通常与 HOMEBREW_PREFIX 相同,或为 Homebrew 子目录。 |
--help
所有内部和外部 Homebrew 命令都可以使用 Homebrew 的 参数解析器 提供样式化的 --help
输出,如 brew services
命令 中所示;或通过包含以 #:
开头的行(在 Bash 和 Ruby 中为注释,后跟 :
字符),如 update.sh
的标头 中所示,该标头使用 brew update --help
打印。
这些命令由 Homebrew 用户贡献,但未包含在 Homebrew 主组织中,也未由安装程序脚本安装。您可以按照上述说明手动安装它们。
请注意,它们在很大程度上未经测试,并且一如既往,请小心在您的机器上运行未经测试的代码。
将任何 gem
包安装到独立的 Homebrew Cellar 位置:https://github.com/sportngin/brew-gem
请注意,也可以使用 brew install brew-gem
安装此命令。
外部命令可以托管在 tap 中,以便用户可以轻松地安装和使用它们。有关创建和维护 tap 的更多详细信息,请参阅 如何创建和维护 tap。
外部命令应添加到 tap 中的 cmd
目录。作为 Ruby 命令实现的外部命令 extcmd
应位于 cmd/extcmd.rb
中(不要忘记 chmod +x
)。
要轻松使用 Homebrew 的参数解析器,请为外部命令复制以下 Ruby 模板。您的实现必须包括以下内容
my-cmd
应命名为 MyCmd
)。cmd_args
块,描述命令及其参数。run
方法,该方法将在执行命令时调用。在 run
方法中,可以使用 args
访问已解析的参数。# frozen_string_literal: true
module Homebrew
module Cmd
class Foo < AbstractCommand
cmd_args do
description <<~EOS
Do something. Place a description here.
EOS
switch "-f", "--force",
description: "Force doing something in the command."
flag "--file=",
description: "Specify a file to do something with in the command."
comma_array "--names",
description: "Add a list of names to the command."
named_args [:formula, :cask], min: 1
end
def run
something if args.force?
something_else if args.file == "file.txt"
end
end
end
end
使用上述内容将生成适当的帮助文本
$ brew foo --help
Usage: brew foo [options] formula|cask [...]
Do something. Place a description here.
-f, --force Force doing something in the command.
--file Specify a file to do something with in the
command.
--names Add a list of names to the command.
-d, --debug Display any debugging information.
-q, --quiet Make some output more quiet.
-v, --verbose Make some output more verbose.
-h, --help Show this message.
用法字符串会根据指定的命名参数的数量和类型自动生成(有关指定命名参数的更多详细信息,请参见下文)。可以通过将正确的用法字符串传递给 usage_banner
方法(放置在 description
方法之前)来覆盖生成的用法字符串。请参阅 brew tap
命令 以获取示例。
使用 named_args
方法指定预期的命名参数的类型和数量。传递一个符号以指示预期的参数类型,一个符号数组以指示应预期多个类型,或一个字符串数组以指定应预期哪些特定选项(请参阅 brew analytics
命令 以获取此示例)。
将一个整数传递给 named_args
的 number
、min
或 max
参数以指定预期的命名参数的数量。请参阅以下示例
# Accept no named args
named_args :none
# Accept any number (including none) of formula arguments
named_args :formula
# Accept exactly one of the specified options as an argument
named_args %w[state off on], number: 1
# Accept at least one argument that is either a formula or a cask
named_args [:formula, :cask], min: 1
# Accept no more than one argument that is a tap
named_args :tap, max: 1
# Accept between one and two named args
named_args min: 1, max: 2