我正在尝试将通过 dpkg 安装的所有软件包收集在 JSON 文件中。
我尝试过这个脚本:
echo [ > installed_packages.json
dpkg-query -W -f '{"name":"${binary:Package}","version":"${Version}","short_description":"${binary:Summary}","description":"${Description}","author":"${Maintainer}","location":"${Filename}","status":{"want":"${db:Status-Want}","status":"${db:Status-Status}","eflag":"${db:Status-Eflag}"},"dependencies":"${Depends}","tags":"${Depends}"},\n' >> installed_packages.json
echo ] >> installed_packages.json
尽管我很快注意到占位符未转义,并且某些字段(如依赖项)需要进行一些处理才能真正有用。
因此,我正在考虑使用命令获取一个简单的列表dpkg-query -W -f '${binary:Package}'
,然后对其进行迭代并单独处理每个字段。尽管我担心dpkg-query
每个包有 10 次调用会对性能造成严重影响。
那么我怎样才能以尽可能便携的方式实现这一目标呢? (该脚本最终将成为许多不同机器上的监视工具的一部分。随后将支持其他包管理器)。
编辑:
由于占位符似乎被设计为兼容 RFC 822(并且其他软件,例如apt-cache show <package>
,无论如何都会生成符合 RFC 822 的输出),我认为sh
将 RFC 822 转换为 JSON 的解决方案将是一个令人惊奇的解决方案。
编辑2:
我只是注意到这很好,但遗憾的是并没有使处理单个值变得更容易。
因此,像 RFC 822 那样正确转义变量或类似的东西将使一切正常工作。
编辑3:
重复调用dpkg-query
绝对会降低性能。通过一次调用,脚本的运行时间远少于一秒。对每个包运行一次会使脚本在 100% CPU 情况下花费 30 秒以上。这是不能接受的...
答案1
几个月前,我编写了一个简单的 ruby 脚本来为我们的监控工具完成非常相似的工作。我只需要名称和版本。我添加了简短描述和作者。任何其他字段可能需要更多处理。这是您可以根据需要进行构建的起点。
#!/usr/bin/env ruby
require 'open3'
# json is only necessary for the pretty_generate at end, remove if not needed
require 'json'
allpkgs = {}
# Edit this command to serve your own purposes
cmd = ("dpkg-query -W -f='${binary:Package};${Version};${binary:Summary};${Maintainer}\n'")
dpkgout, stderr, status = Open3.capture3(cmd)
dpkgout.split("\n").each do |line|
pkginfo = line.split(';')
allpkgs[pkginfo[0]] = { 'version': pkginfo[1], 'short_description': pkginfo[2], 'author': pkginfo[3] }
end
# pretty JSON print, otherwise use 'puts allpkgs'
puts JSON.pretty_generate(allpkgs)