如何提取 rpm 的内容?

Posted

技术标签:

【中文标题】如何提取 rpm 的内容?【英文标题】:How do I extract the contents of an rpm? 【发布时间】:2013-09-18 04:53:40 【问题描述】:

我有一个 rpm,我想把它当作一个 tarball。我想将内容提取到一个目录中,以便检查内容。我熟悉已卸载包的查询命令。我不想简单地列出 rpm 的内容。即

$ rpm -qpl foo.rpm

我想检查 rpm 中包含的几个文件的内容。 我不想安装 rpm。 我也知道 rpm 可以在 %post 部分进行额外的修改,以及如何检查这些。即

$ rpm -qp --scripts foo.rpm

但是在这种情况下,这与我无关。

【问题讨论】:

【参考方案1】:

您尝试过rpm2cpio 命令吗?请看下面的例子:

$ rpm2cpio php-5.1.4-1.esp1.x86_64.rpm | cpio -idmv

/etc/httpd/conf.d/php.conf  
./etc/php.d  
./etc/php.ini  
./usr/bin/php  
./usr/bin/php-cgi  
etc 

【讨论】:

我很惊讶 Linux 发行版没有提供包装器可执行文件来使这更容易(例如 rpmextract bla.rpm),因为这是一个非常常见的操作。用户不需要关心中间的 cpio 格式。 不要惊讶,@AlanEvangelista,这是课程的标准。 这需要 root 权限才能安装 rpm2cpio :( @AlanEvangelista 我很惊讶 rpm 格式如此糟糕。与其他类似的 deb 相比,它们只是遵循 UNIX 哲学的简单档案。 @SumitMurari 当然不好。我只是为 törzsmókus 的困境提供一个解决方案。【参考方案2】:
$ mkdir packagecontents; cd packagecontents
$ rpm2cpio ../foo.rpm | cpio -idmv
$ find . 

供参考:cpio 参数是

-i = extract
-d = make directories
-m = preserve modification time
-v = verbose

我在这里找到了答案:lontar's answer

【讨论】:

"rpm2cpio foo.rpm | cpio -idmv" 对我有用。在当前路径提取 rpm 的内容就足够了。【参考方案3】:

对于那些没有 rpm2cpio 的人,这里是古老的 rpm2cpio.sh 脚本 从 *.rpm 包中提取有效负载。

为后代……和下一代转发。

像这样调用: ./rpm2cpio.sh .rpm | cpio -dimv

#!/bin/sh

pkg=$1
if [ "$pkg" = "" -o ! -e "$pkg" ]; then
    echo "no package supplied" 1>&2
    exit 1
fi

leadsize=96
o=`expr $leadsize + 8`
set `od -j $o -N 8 -t u1 $pkg`
il=`expr 256 \* \( 256 \* \( 256 \* $2 + $3 \) + $4 \) + $5`
dl=`expr 256 \* \( 256 \* \( 256 \* $6 + $7 \) + $8 \) + $9`
# echo "sig il: $il dl: $dl"

sigsize=`expr 8 + 16 \* $il + $dl`
o=`expr $o + $sigsize + \( 8 - \( $sigsize \% 8 \) \) \% 8 + 8`
set `od -j $o -N 8 -t u1 $pkg`
il=`expr 256 \* \( 256 \* \( 256 \* $2 + $3 \) + $4 \) + $5`
dl=`expr 256 \* \( 256 \* \( 256 \* $6 + $7 \) + $8 \) + $9`
# echo "hdr il: $il dl: $dl"

hdrsize=`expr 8 + 16 \* $il + $dl`
o=`expr $o + $hdrsize`
EXTRACTOR="dd if=$pkg ibs=$o skip=1"

COMPRESSION=`($EXTRACTOR |file -) 2>/dev/null`
if echo $COMPRESSION |grep -q gzip; then
        DECOMPRESSOR=gunzip
elif echo $COMPRESSION |grep -q bzip2; then
        DECOMPRESSOR=bunzip2
elif echo $COMPRESSION |grep -iq xz; then # xz and XZ safe
        DECOMPRESSOR=unxz
elif echo $COMPRESSION |grep -q cpio; then
        DECOMPRESSOR=cat
else
        # Most versions of file don't support LZMA, therefore we assume
        # anything not detected is LZMA
        DECOMPRESSOR=`which unlzma 2>/dev/null`
        case "$DECOMPRESSOR" in
            /* ) ;;
            *  ) DECOMPRESSOR=`which lzmash 2>/dev/null`
             case "$DECOMPRESSOR" in
                     /* ) DECOMPRESSOR="lzmash -d -c" ;;
                     *  ) DECOMPRESSOR=cat ;;
                 esac
                 ;;
        esac
fi

$EXTRACTOR 2>/dev/null | $DECOMPRESSOR

【讨论】:

我在使用 Alpine Linux 时收到此错误“unlzma: bad lzma header”。尝试了多个 rpm。【参考方案4】:

有时您会遇到中间 RPM 存档问题:

cpio:号码格式错误 cpio:格式错误的号码 cpio:格式错误的号码 . . . cpio:存档提前结束

这意味着它可以被打包,现在它像往常一样是 LZMA2 压缩,xz

rpm2cpio <file>.rpm | xz -d | cpio -idmv

否则你可以试试:

rpm2cpio <file>.rpm | lzma -d | cpio -idmv

【讨论】:

我刚遇到这个。谢谢! 非常有用。谢谢你,先生! 救命稻草。 @LasseHalbergHaarbye 我将其添加到已接受的答案中。 我收到“格式错误的号码”和“存档过早结束”错误,但发布的解决方案都不适合我。我必须做rpm2cpio &lt;file&gt;.rpm | bsdtar -xf -(没有cpio)才能让它工作。 中间存档对我来说最终是 gzip 格式的,所以我使用 gunzip 而不是 xzlzma 效果很好。【参考方案5】:

大多数发行版都安装了 GUI 应用 file-roller,它可以解压 tar、zip、rpm 等等。

file-roller --extract-here package.rpm

这将提取当前目录中的内容。

【讨论】:

【参考方案6】:

7-zip 了解大多数类型的存档,包括 rpm 和包含的 cpio。

【讨论】:

我试过 7 zip 并且效果很好。【参考方案7】:

tar -xvf &lt;rpm file&gt; 也可以!

【讨论】:

无法使用 .rpm 包重现该内容。你可能想更正你的答案。 这适用于 OS X - 或任何其他使用 tar 变体的系统,该变体在引擎盖下使用 libarchive 我收到错误:这看起来不像 tar 存档。 这适用于我在 MacOS 10.14.1 上使用 bsdtar 2.8.3 - libarchive 2.8.3。这可能取决于使用的压缩类型。 rpm2cpio.sh 脚本似乎会在将其传递给正确的工具进行提取之前检查几种类型的压缩。 由于 SO 的编辑功能不允许我添加 3 个字符来修复答案,因此应该补充一点,这需要 libarchive 的 bsdtar。 Mac 上的 Homebrew 默认将 tar 链接到它,但在其他操作系统上 tar 表示 GNU tar。【参考方案8】:

强大的基于文本的文件管理器mc(午夜指挥官,模糊地提醒诺顿指挥官旧 DOS 时代)具有检查和解压缩 .rpm 和 .rpms 文件的内置功能,只需在 mc 中“打开”.rpm(s) 文件并选择CONTENTS.cpio:对于 rpm,您可以访问安装树,对于 rpm,您可以访问 .spec 文件和所有源包。

【讨论】:

【参考方案9】:

要调试/检查您的 rpm,我建议使用 redline 这是一个 java 程序

用法:

java -cp redline-1.2.1-jar-with-dependencies.jar org.redline_rpm.Scanner foo.rpm

下载:https://github.com/craigwblake/redline/releases

【讨论】:

【参考方案10】:

在 NixOS 中,有 rpmextract。它是 rpm2cpio 的包装器,完全符合 @Alan Evangelista 的要求。 https://github.com/NixOS/nixpkgs/tree/master/pkgs/tools/archivers/rpmextract

【讨论】:

【参考方案11】:

至少在 OpenSuse 中,unrpm 命令与 build 包一起提供。

在一个合适的目录中(因为这是一个存档炸弹):

unrpm file.rpm

【讨论】:

【参考方案12】:

将 .rpm 文件复制到单独的文件夹中,然后运行以下命令 $你的文件.rpm | cpio -idmv

【讨论】:

这应该是评论【参考方案13】:

“解压缩”测试在 CygWin 上失败,CygWin 是最有潜力的平台之一,因为“grep”检查“xz”是区分大小写的。 “压缩:”检查的结果是:

COMPRESSION='/dev/stdin: XZ compressed data'

简单地将“grep -q”替换为“grep -q -i”似乎可以很好地解决问题。

我做了一些更新,特别是添加了一些 cmets 并使用“case”而不是堆叠的“if”语句,并在下面包含了该修复

#!/bin/sh
#
# rpm2cpio.sh - extract 'cpio' contents of RPM
#
# Typical usage: rpm2cpio.sh rpmname | cpio -idmv
#

if [ "$# -ne 1" ]; then
    echo "Usage: $0 file.rpm" 1>&2
    exit 1
fi

rpm="$1"
if [ -e "$rpm" ]; then
    echo "Error: missing $rpm"
fi


leadsize=96
o=`expr $leadsize + 8`
set `od -j $o -N 8 -t u1 $rpm`
il=`expr 256 \* \( 256 \* \( 256 \* $2 + $3 \) + $4 \) + $5`
dl=`expr 256 \* \( 256 \* \( 256 \* $6 + $7 \) + $8 \) + $9`
# echo "sig il: $il dl: $dl"

sigsize=`expr 8 + 16 \* $il + $dl`
o=`expr $o + $sigsize + \( 8 - \( $sigsize \% 8 \) \) \% 8 + 8`
set `od -j $o -N 8 -t u1 $rpm`
il=`expr 256 \* \( 256 \* \( 256 \* $2 + $3 \) + $4 \) + $5`
dl=`expr 256 \* \( 256 \* \( 256 \* $6 + $7 \) + $8 \) + $9`
# echo "hdr il: $il dl: $dl"

hdrsize=`expr 8 + 16 \* $il + $dl`
o=`expr $o + $hdrsize`
EXTRACTOR="dd if=$rpm ibs=$o skip=1"

COMPRESSION=`($EXTRACTOR |file -) 2>/dev/null`
DECOMPRESSOR="cat"

case $COMPRESSION in
    *gzip*|*GZIP*)
        DECOMPRESSOR=gunzip
        ;;
    *bzip2*|*BZIP2*)
        DECOMPRESSOR=bunzip2
        ;;
    *xz*|*XZ*)
        DECOMPRESSOR=unxz
        ;;
    *cpio*|*cpio*)
        ;;
    *)
        # Most versions of file don't support LZMA, therefore we assume
        # anything not detected is LZMA
        DECOMPRESSOR="`which unlzma 2>/dev/null`"
        case "$DECOMPRESSOR" in
            /*)
                DECOMPRESSOR="$DECOMPRESSOR"
                ;;
            *)
                DECOMPRESSOR=`which lzmash 2>/dev/null`
                case "$DECOMPRESSOR" in
                    /* )
                        DECOMPRESSOR="lzmash -d -c"
                        ;;
                    *  )
                        echo "Warning: DECOMPRESSOR not found, assuming 'cat'" 1>&2
                        ;;
                esac
                ;;
        esac
esac

$EXTRACTOR 2>/dev/null | $DECOMPRESSOR

【讨论】:

【参考方案14】:

在使用 KDE 的 Manjaro 上,Ark 可以处理。

【讨论】:

【参考方案15】:

只需运行这个:

$rpm -ivh package_name.rpm

如果您没有超级用户权限,请使用sudo -i 命令然后执行此命令。 如果没有 rpm 包,请安装 rpm 包。

【讨论】:

似乎对我不起作用。我收到以下错误:警告:rstudio-server-rhel-2021.09.2-382-x86_64.rpm: Header V4 RSA/SHA256 Signature, key ID e331692f: NOKEY error: can't create transaction lock on /var/lib/ rpm/.rpm.lock(权限被拒绝)

以上是关于如何提取 rpm 的内容?的主要内容,如果未能解决你的问题,请参考以下文章

如何在不安装 RPM 的情况下“重新打包”一个 RPM 文件,例如 cpio2rpm?

Linux提取RPM包文件(cpio命令)详解

如何使用 YUM 列出一个包的内容?

RPM包校验

如何提取DELPHI中MEMO中某一行的内容?

如何使用word提取文章中的关键词