如何提取rpm的内容?


154

我有一个rpm,我想像一个tarball一样对待它。我想将内容提取到目录中,以便检查内容。我熟悉已卸载软件包的查询命令。我不只是想要列出rpm的内容。即

$ rpm -qpl foo.rpm

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

$ rpm -qp --scripts foo.rpm

但是,在这种情况下,我不需要担心。

Answers:


184

您尝试过该命令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 

28
我很惊讶Linux发行版没有提供包装可执行文件来简化此操作(例如rpmextract bla.rpm),因为这是非常常见的操作。用户无需关心中间cpio格式。
艾伦·

2
@AlanEvangelista,请不要惊讶,这是课程的标准。
ngreen

这需要安装rpm2cpio :( root访问权限
törzsmókus

9
@AlanEvangelista我对rpm如此糟糕的格式感到惊讶。与其他类似deb的文件相比,它们只是遵循UNIX哲学的简单档案。
Trismegistos 2015年

1
@SumitMurari当然不好。我只是为törzsmókus的困境提供解决方案。
MirroredFate

66
$ mkdir packagecontents; cd packagecontents
$ rpm2cpio ../foo.rpm | cpio -idmv
$ find . 

供参考:cpio参数是

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

我在这里找到了答案:lontar的答案


1
“ rpm2cpio foo.rpm | cpio -idmv”对我有用。在当前路径上提取rpm的内容就足够了。
parasrish

32

对于那些没有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:错误的lzma标头”。尝试了多个rpm。
jekennedy

27

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

cpio:格式错误的数字
cpio:格式错误的数字
cpio:格式错误的数字
。。。
cpio:存档过早结束

这意味着它可以打包,这些天像往常一样是LZMA2压缩,方法是xz

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

否则,您可以尝试:

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

2
我刚遇到这个。谢谢!
山姆·斯托林加

2
很有用。谢谢你,先生!
ILIV 2015年

1
救生员。@LasseHalbergHaarbye我已将其添加到接受的答案中。
约瑟夫·法拉

我遇到了“格式错误的数字”和“归档的结尾过早”错误,但是没有一个发布的解决方案对我有用。我必须要做rpm2cpio <file>.rpm | bsdtar -xf -(没有cpio)才能工作。
jackkamm '17

中间档案最终对我来说是gzip格式的,所以我用gunzip代替了xzlzma工作正常。
jayhendren

9

大多数发行版都安装了GUI应用程序文件滚轮,可解压缩tar,zip,rpm等文件。

file-roller --extract-here package.rpm

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



5

您也可以做tar -xvf <rpm file>


无法使用.rpm软件包复制该文件。您可能需要更正您的答案。
gvlasov

9
这适用于OS X-或任何其他使用其变体在tar幕后使用libarchive的系统。
Glenjamin

2
我得到了错误:这看起来不像tar存档。
wp-overwatch.com '18

这在MacOS 10.14.1和bsdtar 2.8.3-libarchive 2.8.3上为我工作。这可能取决于所使用的压缩类型。rpm2cpio.sh脚本在将其传递到正确的工具进行提取之前,似乎已经检查了几种压缩类型。
18x

由于SO的编辑功能不允许我添加3个字符来固定答案,因此应该补充一点,这需要libarchive的bsdtar。Mac上的Homebrew tar默认情况下会链接到它,但在其他OS上则tar意味着GNU tar。
Atemu

5

强大的基于文本的文件管理器mc(Midnight Commander,隐约地提醒Norton Commander DOS时代)具有检查和解压缩.rpm和.rpms文件的内置功能,只需“打开” .rpm(s)文件在mc中,然后选择CONTENTS.cpio:对于rpm,您可以访问安装树,对于rpm,您可以访问.spec文件和所有源软件包。




1

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

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

unrpm file.rpm

1

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


这应该是评论
ketan '16

1

在CygWin(最强大的平台)上,“ DECOMPRESSION”测试失败,原因是“ xz”的“ grep”检查区分大小写。“ COMPRESSION:”检查的结果是:

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

到处简单地将'grep -q'替换为'grep -q -i'似乎可以很好地解决此问题。

我做了一些更新,特别是添加了一些注释,并使用“ 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

1

7-Zip可以提取内容。它的工作方式与tar.gz文件相同。压缩文件内的压缩文件。

在安装了7-Zip的Windows 7 Pro上:

右键单击rpm文件。将鼠标悬停在上下文菜单中的7-Zip上。选择解压缩为“文件名”。

输入文件名文件夹。

右键单击cpio文件。将鼠标悬停在上下文菜单中的7-Zip上。选择解压缩为“文件名”。

大功告成 带有“文件名”的文件夹包含提取的内容以供检查。

我知道Linux的人鄙视让事情变得简单的方法,但是从长远来看,如果您不得不花时间寻找解决此类简单问题的解决方案,那么,效率低下会浪费您的钱。

考虑到您的Linux专家轻视高效的简单性,我非常怀疑Linux版本的7-Zip是否会以完全相同的方式执行相同的操作。

当您可以使彻头彻尾的笨蛋变得困难并且同时声称自己是天才时,为什么要轻松一点呢?

只是为了清楚起见;我不是Windows迷。我实际上正在考虑过渡到Linux。我只是忍不住有机会将Windows开发人员认为是常识和最佳开发人员实践的机会涂在脸上。

只是很高兴这是我发布的内容,而且您没有Mark Harmon站在您旁边。特工Leroy Jethro Gibbs会因为不使用头部而给您打耳光。

我不知道这是什么吉布斯规则,但是规则是:不要让事情变得比自己更难。

现在我们来看看谁需要休假。照顾自己!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.