Homebrew:如何列出最后安装的N个软件包



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

实现这一目标的最佳(可能也是最快)方法是什么?

请注意,我的Ruby并不流利,所以任何"破解Homebrew代码来做你想做的事"的建议都会让我紧张。。。

到目前为止我尝试了什么

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

到目前为止我学到了什么

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

当然,我发现brew info --installed选项,但目前,它只适用于JSON输出。由于JSON输出将而不是告知浇注日期,因此这没有用处。

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

  • 使用brew info --installed --json=v1 | jq "map(.name)" > inst.json提取所有已安装的程序包名称
  • 分析结果,使其成为一行,例如cat inst.json | tr -d 'nr[]",'
  • 现在用这一行运行brew info --formula(将所有内容都视为公式以避免警告),将结果通过管道传输到另一个文件(例如all-installed.txt)中
  • 浏览该文件,提取包含公式名称和日期的行,并使用类似cat all-installed.txt | sed -E 's/([[:alnum:]]+):? stable.*n(.*n){3,7}^ Poured from bottle on (.*)$/1 -- 3\n/g' | sort | tail -40的方法对其进行格式化——其想法是只包含日期和公式名称的行,这样就可以很容易地对其进行排序[注意:我知道显示的regex不起作用,在我放弃这种方法之前,它只是一次失败尝试的一部分]

混乱。处理所有事情也需要花费大量时间。如果您准备盯着空白屏幕等待几分钟,则可以将所有内容放在一行中,并避开中间文件。

快速而肮脏的方法

我试图查找a)安装日志b)brew将存储我试图提取的信息(并且brew info可以访问)的某种数据库。我发现的大多数"日志"实际上都与修补单个软件包有关(因此,如果出现问题,你可以给维护人员发电子邮件)。然而,纯属偶然,我注意到每个包的/usr/local/Cellar/中都有一个INSTALL_RECEIPT.json似乎有brew info --json=v1 package-name的输出。无论这个文件的目的是什么,它都有一点宝贵的信息:它是在安装这个软件包的那天创建的!

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

例如,要获得最后40个安装的公式:

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

这运行得相当快,我确实成功地获得了另一个项目所需的东西(列出了我必须安装的最后几个公式,以便运行我试图在macOS下编译的某个软件包,并记录所需的内容),但我一直想知道这是否是"最好"的方法。当然,它已经足够快了——使用标准工具遍历文件系统树要比期望Ruby做慢节奏的工作快得多——但我怎么知道我有"正确"的信息呢?所有程序包都有INSTALL_RECEIPT.json吗?如果Homebrew的核心开发人员想彻底改变整个目录结构呢?或者停止写入INSTALL_RECEIPT.json文件,因为他们在"其他地方"使用数据库(哪里?),而这变得多余了?换句话说,我如何才能以经得起未来考验的方式,仅依靠brew命令已经提供的任何信息来确定我想要什么?

无论如何,为了便于讨论,我非常欢迎看到一些关于如何正确地执行的建议,并且不会像我对stat所做的那样"作弊"(例如,根本不执行brew命令,而是依赖于文件系统本身)。

或者也许这样的功能不存在,我应该就Homebrew的GitHub问题提出功能请求?(毕竟,Debian/UubuntuLinux用户有一种方法可以使用apt的一些参数和一些解析来获得这些信息……我们应该得到同样的信息,甚至更好!😄)

;酿造列表";命令有一个-t选项:

按时间修改对公式和/或容器进行排序,首先列出最近修改的。

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

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

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

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

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

因此很明显,CCD_;Cellar";。

如果brew list的速度太慢,我认为将HOMEBREW_PREFIX(如brew --prefix所示)与CellarCellar/*/*/INSTALL_RECEIPT.json结合使用是合理的

.time

每个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

最新更新