轻松解压 DEB、编辑 postinst 和重新打包 DEB

Joh*_*per 166 package-management

我正在尝试安装英特尔的 OpenCL SDK,但 DEB 文件是来自 RPM 的错误转换(请参阅此处了解好奇)。我需要postinst在他们提供的 DEB 中编辑脚本。

如何获取现有的 DEB,提取内容(包括控制信息),然后重新打包内容以制作新的 DEB?我只会编辑文件,不会添加或删除文件。

Gil*_*il' 263

操作 deb 包的主要命令是dpkg-deb.

要解压缩包,请创建一个空目录并切换到该目录,然后运行dpkg-deb以提取其控制信息和包文件。使用dpkg-deb -b重建包。

mkdir tmp
dpkg-deb -R original.deb tmp
# edit DEBIAN/postinst
dpkg-deb -b tmp fixed.deb
Run Code Online (Sandbox Code Playgroud)

请注意,除非您的脚本以 root 身份运行,否则文件的权限和所有权将在提取阶段损坏。避免这种情况的一种方法是在fakeroot. 请注意,您需要在 下运行整个序列fakeroot,而不是dpkg-deb单独运行每个序列,因为它fakeroot是保存无法按原样创建的文件权限的过程。

fakeroot sh -c '
  mkdir tmp
  dpkg-deb -R original.deb tmp
  # edit DEBIAN/postinst
  dpkg-deb -b tmp fixed.deb
'
Run Code Online (Sandbox Code Playgroud)

您可以保持数据存档完好无损,只修改控制存档,而不是弄乱权限。dpkg-deb没有提供一种方法来做到这一点。幸运的是,deb 包采用标准格式:它们是ar档案。因此,您可以使用ar提取控制档案,修改其文件,并ar再次使用以将控制档案替换为新版本。

mkdir tmp
cd tmp
ar p ../original.deb control.tar.gz | tar -xz
# edit postinst
cp ../original.deb ../fixed.deb
tar czf control.tar.gz *[!z]
ar r ../fixed.deb control.tar.gz
Run Code Online (Sandbox Code Playgroud)

如果您修改了包中的任何内容,您应该添加一个更改日志条目并更改版本号。操作 Debian 软件包的基础结构假定如果两个软件包具有相同的名称和版本,则它们是同一个软件包。在版本号末尾的debian_revision部分添加后缀;出于排序的原因,后缀应该以 开头~,例如1.2.3-4.1变成1.2.3-4.1~johnjumper1

您可以使用 Emacs,而不是使用 shell 工具。该dpkg-dev-el(它是它自己的上游,因为这是一个本地 Debian 包)包含编辑.deb文件和编辑 Debian 更改日志的模式。Emacs 可以交互使用或脚本化使用。

  • 您也可以使用 [fpm](https://github.com/jordansissel/fpm) 的 `-e` 开关来更改控制文件:`fpm -e -s deb -t deb ../old.deb` . 这将在您的编辑器中打开控制文件。 (4认同)
  • 谢谢。这很有用。使用 `dpkg-deb -R` 模式被保留,`dpkg-deb -b` 将提取文件的 `uid:gid` 重置为 `0:0`。不需要 fakeroot(我想如果存档中有 set{u,g}id 文件可能会出现问题,但在我的情况下并非如此。 (2认同)
  • @PSkocik 不仅是setxid 文件,还有例如`/etc` 或`/var` 下需要属于特定组的文件和目录。 (2认同)

小智 8

您可以将fpm--after-install替换postinst脚本的选项一起使用,如下所示:

fpm -e --after-install ../DEBIAN/postinst.new -s deb -t deb ../old.deb
Run Code Online (Sandbox Code Playgroud)

  • 在 Debian/Ubuntu 上安装 fpm: sudo apt-get install ruby​​-dev build-essential; 须藤宝石安装 fpm (2认同)