swift 发布于 2024年12月09日
说到包管理工具,几乎已经成为现代操作系统或者开发平台不可或缺的工具软件。 如果你有过服务端管理经验的话,你一定会用过诸如 yum 这样的工具,只需要几条命令,就把需要的服务全都安装上。
无论我们平时做开发,或是管理服务器,都免不了用到一些第三方依赖包。即便是架设一个最简单的 web 服务器,你至少也需要安装一个 nginx。
包管理工具的基本功能就是提供一个集中的平台,可以在这里找到大部分流行的组件,而不用费力的到每个软件自己的主页去下载安装。 只需要输入简单的命令,就可以直接安装。 并且包管理工具还会帮助用户管理所有这些包的版本,以及它们之间的依赖关系。
像刚才说的架设 web 服务器的例子,如果没有包管理工具,我们就需要找到每个组件的下载位置,还要手动管理它们的更新,依赖关系等等,这些事情就需要消耗掉不少的精力。 好在包管理工具已经为我们处理好了这一切,我们要做的只是安装,使用。
macOS 上的包管理刚才举的是服务端管理的例子,那么包管理在我们自己的开发机上有什么用呢? 下面就逐步给大家介绍。 Homebrew 作为 macOS 包管理工具的后起之秀,在近一两年可谓是风生水起。 相比它的前辈,macports 和 Fink 而言,它的整体设计更加符合现代的开发环境,并且平台的更新速度也更快。
废话不再多说,开始进入正题,无论你是初次接触 Homebrew,又或是已经用过它,但是还没有深入了解,后面的内容我相信都会对你有所帮助。
安装与使用使用 Homebrew 第一步就是安装它,这个在它的主页 https://brew.sh 上有明确的文档,最简单的方式只需要一行命令:
这是一个 ruby 脚本,执行这个安装脚本就可以完成 Homebrew 所有安装操作。 咱们继续,安装完成后,我们就可以使用 brew 命令安装需要的包了:
安装的完整过程如下图所示:
从上面图中的最后一行可以看到,node 被安装到了 /usr/local/Cellar
目录中。 通过 Homebrew 安装的所有包都会被放在这里。 这样做有几个好处,一个是方便集中管理,删除不再使用的软件包,省去了大量软件包散落在各处带来日后清理的头疼问题。另外可以方便更集中的权限管理。
为了更好的说明这个问题,还是给大家举个具体的例子,比如我们前面命令中安装的 node 软件。 如果不使用 Homebrew, 而用它官网提供的安装程序,那么安装完成后,会创建如下文件:
-rwxrwxr-x 1 spring admin 30994272 10 3 09:55 node
lrwxr-xr-x 1 502 staff 38 10 16 09:57 npm -> ../lib/node_modules/npm/bin/npm-cli.js
/usr/local/include
drwxrwxr-x 42 spring admin 1344 10 3 09:55 node
/usr/local/lib
drwxrwxr-x 3 spring admin 96 10 3 09:54 node_modules
/usr/local/lib/dtrace
-rw-rw-r-- 1 spring admin 12324 10 3 09:50 node.d
/usr/local/share/doc
drwxrwxr-x 5 spring admin 160 10 3 09:54 node
/usr/local/share/man/man1
-rw-rw-r-- 1 spring admin 7849 10 3 09:48 node.1
/usr/local/share/systemtap/tapset
-rw-rw-r-- 1 spring admin 2361 10 3 09:48 node.stp
这里面路径部分是所在目录,下面的内容是当前目录的内容。大家看到了,一个 nodejs 环境,安装看起来不难,但它却会在这么多的位置创建文件。 当然,如果你一直在同样的环境使用它,没什么问题。 但如果有一天你不需要它了,想删除掉,就比较麻烦了,至少在我写这篇文章的时候,NodeJS 官方也还没提供方便的卸载工具。 也就是说,你必须像我现在这样清楚的列出它所有文件的位置,才能干净的将它删除掉。这个现象存在于大多数我们常用的工具软件中。
再来看看 Homebrew 是如何解决这个问题的,下面是使用 Homebrew 安装 node 后文件的存放位置:
lrwxr-xr-x 1 marspro admin 29 10 16 12:03 node -> ../Cellar/node/8.7.0/bin/node
lrwxr-xr-x 1 marspro admin 46 10 16 12:03 npm -> /usr/local/lib/node_modules/npm/bin/npm-cli.js
/usr/local/include
lrwxr-xr-x 1 marspro admin 33 10 16 12:03 node -> ../Cellar/node/8.7.0/include/node
/usr/local/lib
drwxr-xr-x 4 marspro admin 128 10 17 14:01 node_modules
/usr/local/lib/dtrace
lrwxr-xr-x 1 marspro admin 41 10 16 12:03 node.d -> ../../Cellar/node/8.7.0/lib/dtrace/node.d
/usr/local/share/doc
lrwxr-xr-x 1 marspro admin 38 10 16 12:03 node -> ../../Cellar/node/8.7.0/share/doc/node
/usr/local/share/man/man1
lrwxr-xr-x 1 marspro admin 48 10 16 12:03 node.1 -> ../../../Cellar/node/8.7.0/share/man/man1/node.1
/usr/local/share/systemtap/tapset
-rw-r--r-- 1 marspro admin 3495 10 11 20:36 node.stp
初步看上去,好像和前面的整体上没有什么区别,但仔细观察你会发现,之前目录中的文件都变成了符号链接,并且指向 Cellar 目录中。 比如之前的:
-rwxrwxr-x 1 spring admin 30994272 10 3 09:55 node
在通过 Homebrew 安装后,变成了:
lrwxr-xr-x 1 marspro admin 29 10 16 12:03 node -> ../Cellar/node/8.7.0/bin/node
也就是说,虽然 node 安装后的目录结构没变,但相应的位置已经变成了符号链接,而 node 实际的文件都存放在了 /usr/local/Cellar
目录中。 也就是我们前面说的 Homebrew 模块主目录。 当你想删除 nodejs 的时候,只需要运行:
这一条命令就可以完整的删除之前安装的 nodejs 所有内容,这里也包括在 /usr/local/ 中创建的那些符号链接。你甚至还可以用另外一条命令暂时的停用 node:
使用 unlink,只会删除符号链接,但并不会删除程序本身, /usr/local/Cellar 目录中的程序文件还依然存在。这个功能在某些场景中非常有用,比如你需要某个程序包暂时失效,用于调试你正在进行的开发。
当 unlink 调试结束后,再运行 link 命令,就可以把相应的程序包恢复回来:
包管理的好处是不是体现出来了。 你还可以用 brew info 命令查看当前安装的 node 版本:
输出:
Platform built on V8 to build network applications
https://nodejs.org/
/usr/local/Cellar/node/8.7.0 (3,830 files, 45.5MB) *
Poured from bottle on 2017-10-18 at 00:29:19
From: https://github.com/Homebrew/homebrew-core/blob/master/Formula/node.rb
这条命令可以列出这个程序包的完整信息,包括它的版本,安装位置,等等。 从这里可以看到,我们当前安装的 node 版本是 8.7.0。 Homebrew 还允许我们指定安装的版本号,比如:
会安装 6.x 版本的 node。 同样,这个版本的 node 也会被保存到 /usr/local/Cellar 目录中。 这样,我们同时就有了两个 node 版本。
可定制信息查询Homebrew 也为我们提供了非常灵活的信息查询能力。 通过 brew info
命令和 jq
模块的结合。 首先我们可以安装 jq
模块:
jq
是一个在命令行中处理 JSON 数据的模块。 而 brew info
命令除了我们刚才展示的方法,还支持原生 JSON 格式的输出, 还是以我们刚才的 node 模块为为例:
这里 info 命令多了一个 --json=v1
参数,这表示使用 JSON 格式输出, 随后传递给 jq 做格式化输出,最终的结果如下:
可以看到,这里给出的信息非常全,包括当前版本,安装类型,依赖关系等等。 除了查询单个包的信息之外,还可以利用 jq 的能力做一些条件查询,比如:
jq 命令后面的参数是查询条件。 linked_keg
表示已经建立符号链接的包。 也就是相当于前面提到的没有被 brew unlink
的。 后面的 .name 表示我们只需要显示包的 name 属性, 也就是名称。
这只是一个简单的查询例子,通过这个命令,你几乎可以用任何方式访问 Homebrew 的内部数据。 尤其对于只需要数据的程序,比如对于开发一个显示本地 Homebrew 内容的 UI 程序,这些数据可以非常方便的获取到。
BottlesBottles 是 Homebrew 中的一个专用名词。 它表示直接用二进制形式发布的包。 我们在使用 brew install
安装程序包的时候有两种方式,一个是下载源代码然后在本地构建,另外一个是直接下载已经编译好的二进制包。 而 Bottles 就是预编译好的二进制包。
如果一个源包含预编译的 Bottle, 我们在使用 brew install
的时候会自动使用它。 如果出于某些原因,你不想使用预编译的包,就可以加上 --build-from-source
选项:
这样相应的安装包就会在你的本机上面构建。一般而言,直接在本机构建源代码安装速度会比较慢,这也是为什么 Homebrew 会提供 Bottles 预编译包的原因之一, 但在有些场景下,可能会需要自己来编译,这个选项就有作用了。
TapsHomebrew 主要是基于 Git 进行包管理的, 之前如果了解过包管理系统的同学应该会知道这个特性,每个包管理工具都会有一个主仓库,和一些可选的功能仓库。 这样做的主要是为了让软件包整理有序。 因为当前所有可用的软件包加在一起会非常庞大,都放到一个仓库中会造成很大的性能损耗,并且这些庞大的包中有相当一部分是比较小众不常用的。 所以一般包管理工具会把那些常用的软件包放到主仓库,其他的软件包根据功能特性组织到可选的功能仓库中。
Homebrew 的 Taps 就是这个仓库的概念。 我们可以试着输入命令 brew tap
, 你应该会看到这样的输出:
默认情况下,Homebrew 只包含 homebrew/core
这个仓库,也就是它的主仓库。当然 Homebrew 还提供了一些功能仓库,比如:
homebrew/php // php 相关模块的仓库
homebrew/science // 科学计算工具仓库
如果想加载任何一个仓库,只需要执行 brew tap
命令:
除了 Homebrew 自身提供的这些仓库之外,还可以加载任何的第三方仓库,只要这些仓库符合 Homebrew 的规范,都可以正常使用。 Homebrew 官网中也列举出了一些有用的 Taps 供大家参考: https://docs.brew.sh/Interesting-Taps-and-Forks.html。
用户数据统计Homebrew 会使用 Google Analytics 记录匿名用户数据, 这点在它的官网上也有明确说明:https://docs.brew.sh/Analytics.html。
一个好消息是,你可以控制你的本地客户端是否发送这些匿名数据:
Analytics is enabled.
UUID: D8B7E7E8-2FF5-4110-85F9-3559F1150CCF
brew analytics
命令可以检测当前 Homebrew 是否开启了用户数据上传,如果开启,会向上面那样给出你的 UUID。 如果你不想上传这些行为数据可以运行:
来关闭数据上传。 同样,你还可以重新生成统计的 UUID:
那么这个匿名数据用来做什么呢,主要是用来记录整体仓库使用情况的,它不会具体到每一个人,只是用来分析整体趋势,以便 Homebrew 能够更好的完善自身。 并且这些数据对用户也都是开放的:https://brew.sh/analytics/
这个页面里面列出了目前开放的数据统计,比如这个在一段时间内安装量的数据:
从这里就可以看出这些安装包的整体趋势,还是比较有价值的数据。
Homebrew 命名原则Homebrew 从字面意思上翻译,就是自酿啤酒的意思。 它的一切命名规范都来自于这个主题,比如在安装好一个包的时候,命令行中会出现一个啤酒表情:
知道这个背景,你就应该了解这个表情不是随意放上去的,正好切合了 Homebrew 的主题。
还记得我们最开始提到的包的安装位置么, /usr/local/Cellar
。 Cellar 这个词是酒窖的意思。是不是又和主题吻合上了。
这里面是 Homebrew 完整的命名方式含义 https://docs.brew.sh/Formula-Cookbook.html 看完之后相信你会更理解 Homebrew 各种名称的含义了。
总结这篇文章算是对 Homebrew 给大家做了一个概述,把它的主要功能,能做的事情做了介绍。也希望通过这个介绍,能帮助大家对 Hombrew 的了解更多一些。
如果你觉得这篇文章有帮助,还可以关注微信公众号 swift-cafe,会有更多我的原创内容分享给你~
本站文章均为原创内容,如需转载请注明出处,谢谢。
关注微信公众号
发现更多精彩 swift-cafe |