Homebrew:如何列出最近安装的 N 个包?

Homebrew: how to list the N last installed packages?

简单地说:我想列出我用 Homebrew 安装的最后 N 个包。

完成此任务的最佳(可能最快)方法是什么?

请注意,我的 Ruby 不是很流利,所以对 'hack the Homebrew code to do what you want' 的任何建议都会让我感到紧张...

到目前为止我尝试了什么

  1. 阅读手册页、文档、Homebrew 网站、Whosebug,用谷歌搜索各种不同的问题等。到目前为止运气不好。
  2. brew info [formula|cask] 实际上会告诉 formula/cask 被 倒出 的日期(我假设这意味着 'installed' 在 Homebrewosphere 之外)。所以这个值必须写在某个地方——数据库?日志?
  3. 也许有一个选项可以通过 JSON API 提取倒酒日期信息?但事实是,使用 Homebrew 3.1.9-121-g654c78c,我无法在 JSON 输出中获得任何 poured-date 或类似元素......我得到的唯一日期与 git(大概是因为它们对 Homebrew 的内部工作更有用)。从理论上讲,这可以告诉我我安装的公式的 'newest' 版本是什么,但是 不是 order 我已经安装了它们——换句话说,我可以在昨天安装一个一年前的版本,我不需要知道它是一年前的,我只想知道我昨天安装了它!

到目前为止我学到了什么

虽然我不知道如何检索该信息,但我确定它那里,因为brew info ... 给出 正确的 倒出特定配方的日期。因此,一种可能的解决方案是从 brew info 捕获 所有 信息,然后对其执行 grep;因此,像 brew info | grep Poured 这样的东西应该能给我想要的东西。不用说,这需要 eternities 到 运行(事实上,我从来没有完成它——几分钟后我放弃了)。

当然,我发现 一个 brew info --installed 选项 — 但目前,它仅适用于 JSON 输出。由于 JSON 输出将 不会 告诉倾倒日期,这没有用。

一种可能是按以下方式进行:

凌乱。处理所有事情也需要很多时间。如果您准备盯着空白屏幕等待几分钟,您可以将所有内容放在一行中并避免使用中间文件。

快速而肮脏的方法

我试图寻找 a) 安装日志; b) 某种数据库,其中 brew 将存储我试图提取的信息(并且 brew info 可以访问)。我发现的大多数 'logs' 实际上都与修补单个软件包有关(这样如果出现问题,您大概可以给维护者发电子邮件)。然而,一个偶然的机会,我注意到每个包裹在/usr/local/Cellar/里面都有一个INSTALL_RECEIPT.json似乎 brew info --json=v1 package-name 的输出。无论此文件的用途是什么,它都有一点宝贵的信息:它是在安装此软件包的日期创建的!

这对我来说真是太幸运了,因为 现在 我可以简单地 stat 这个文件并获得它的创建时间戳。因为公式目录的格式非常好并且易​​于解析,所以我可以做一些非常简单的事情,只需使用 stat 和一些格式化的东西,这让我花了很长时间才弄清楚(主要是因为 BSD 下的 stat受 SysV 启发的 Unix 有不同的选择 Linux).

例如获取最近安装的40个公式:

stat -t '%Y%m%d%H%M' -f "%Sc %N %@" /usr/local/Cellar/*/*/INSTALL_RECEIPT.json | sort | tail -40

这个 运行 相当快,我当然设法得到了我 wanted/needed 另一个项目的确切内容(列出我必须安装的最后几个公式 运行 我试图在 macOS 下编译并记录所需内容的某个软件包),但我一直想知道这是否是 'best' 方法。当然,它足够快 — 使用标准工具遍历文件系统树比期望 Ruby 执行其慢节奏工作要快得多 — 但我怎么知道我有 'correct' 信息? 所有 包都有 INSTALL_RECEIPT.json 吗?如果 Homebrew 核心开发人员想到完全改变整个目录结构怎么办?或者停止写入那个 INSTALL_RECEIPT.json 文件,因为他们使用数据库 'elsewhere'(在哪里?),这变得多余了?换句话说——我怎样才能以面向未来的方式找出我想要的东西,只依赖于 brew 命令已经提供的任何信息?

无论如何,为了争论,我非常欢迎看到一些关于如何正确的建议——而且没有'cheating',因为我使用 stat 完成(例如,根本不通过 brew 命令,而是依赖文件系统本身)。

或者这样的功能可能不存在,我应该对 Homebrew 的 GitHub 问题提出功能请求? (毕竟,Debian/Ubuntu Linux 用户 有办法 get that information 使用 apt 的一些参数和一些解析.. .我们'deserve'一样,甚至更好!)

“brew list”命令有一个 -t 选项:

Sort formulae and/or casks by time modified, listing most recently modified first.

因此要获得最近的 40 个,您可以这样写:

brew list -1t 2> /dev/null | head -n 40

还有一个 -l 选项,显示使用的时间戳。

运行 brew list -t -v 显示引擎盖下发生的事情;在我的机器上,输出开始于:

==> Formulae
ls -t /usr/local/Cellar

很明显brew list(目前)依赖于“地窖”。

如果 brew list 对您来说太慢了,我相信将 HOMEBREW_PREFIX(如 brew --prefix 所揭示)与 Cellar 结合使用是合理的或 Cellar/*/*/INSTALL_RECEIPT.json

.时间

每个 INSTALL_RECEIPT.json 中的 JSON 对象都有一个 .time 键,这可能比文件或目录时间戳更可靠,因此您可能会考虑这样的事情 bash 脚本:

CELLAR=$(brew --prefix)/Cellar
jq -nr --arg cellar "$CELLAR" '
  [inputs | {time, file: (input_filename|sub($cellar;"") | sub("/INSTALL_RECEIPT.json";""))}]
  | sort_by(.time)[-40:][]
  | .file
' $CELLAR/*/*/INSTALL_RECEIPT.json