Question

I have an rpm and I want to treat it like a tarball. I want to extract the contents into a directory so I can inspect the contents. I am familiar with the querying commands of an uninstalled package. I do not simply want a list of the contents of the rpm. i.e.

$ rpm -qpl foo.rpm

I want to inspect the contents of several files contained in the rpm. I do not want to install the rpm. I am also aware of the rpms ability to do additional modifictions in the %post sections, and how to check for those. i.e.

$ rpm -qp --scripts foo.rpm

However in this case that is of no concern to me.

Was it helpful?

Solution

Did you try the rpm2cpio commmand? See the example below:

$ 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 

OTHER TIPS

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

For Reference: the cpio arguments are

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

I found the answer over here: lontar's answer

For those who do not have rpm2cpio, here is the ancient rpm2cpio.sh script that extracts the payload from a *.rpm package.

Reposted for posterity … and the next generation.

Invoke like this: ./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

Sometimes you can encounter an issue with intermediate RPM archive:

cpio: Malformed number
cpio: Malformed number
cpio: Malformed number
. . .
cpio: premature end of archive

That means it could be packed, these days it is LZMA2 compression as usual, by xz:

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

otherwise you could try:

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

Most distributions have installed the GUI app file-roller which unpacks tar, zip, rpm and many more.

file-roller --extract-here package.rpm

This will extract the contents in the current directory.

You can simply do tar -xvf <rpm file> as well!

7-zip understands most kinds of archives, including rpm and the included cpio.

The powerful text-based file manager mc (Midnight Commander, vaguely reminding the Norton Commander of old DOS times) has the built-in capability of inspecting and unpacking .rpm and .rpms files, just "open" the .rpm(s) file within mc and select CONTENTS.cpio: for an rpm you get access to the install tree, for an rpms you get access to the .spec file and all the source packages.

To debug / inspect your rpm I suggest to use redline which is a java program

Usage :

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

Download : https://github.com/craigwblake/redline/releases

In NixOS, there is rpmextract. It is a wrapper around rpm2cpio, exactly as @Alan Evangelista wanted. https://github.com/NixOS/nixpkgs/tree/master/pkgs/tools/archivers/rpmextract

In OpenSuse at least, the unrpm command comes with the build package.

In a suitable directory (because this is an archive bomb):

unrpm file.rpm

Copy the .rpm file in a separate folder then run the following command $ yourfile.rpm | cpio -idmv

On Manjaro using KDE, Ark can handle it.

The "DECOMPRESSION" test fails on CygWin, one of the most potentiaally useful platforms for it, due to the "grep" check for "xz" being case sensitive. The result of the "COMPRESSION:" check is:

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

Simply replacing 'grep -q' with 'grep -q -i' everywhere seems to resolve the issue well.

I've done a few updates, particularly adding some comments and using "case" instead of stacked "if" statements, and included that fix below

#!/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

simply run this:

$rpm -ivh package_name.rpm

if you don't have super user permissions, use sudo -i command then execute this.
if you don't have rpm package, install rpm package.

If your system has rpm2archive installed, you can run:

rpm2archive package.rpm

This converts rpm package into a compressed tar archive package.rpm.tgz. Now you can extract it using:

tar -xvf package.rpm.tgz

This was earlier noted by Hi-Angel in his comment.

Sources:

  1. rpm2archive man page
  2. It was released with rpm 4.12.0-alpha (it's fairly new)
  3. On Debian and its derivatives, it is included with rpm2cpio package.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top