<<< Back to the Linux Tips Index

16th January 2019

rpm2cpio in one move

Extracting an RPM without installing it

Sometimes you want to extract the contents of an RPM without actually installing it. Maybe you're not even on an RPM-based system (such as Debian, or Ubuntu).

The rpm2cpio utility (part of the normal rpm package; which is available even for non-RPM-based Linux distributions) will extract the contents of an RPM into a CPIO archive. CPIO isn't a widely-used format these days, so many people find this unfamiliar. But that is what RPM uses internally, so the rpm2cpio utility just strips out that part of the RPM and spits it to standard output.

You can use this to extract the files directly into your local filesystem.

Here, you are in the /tmp/extractme directory, and the files which would have been installed by installing the RPM will appear relative to your current directory.

steve@linux:/tmp/extractme$ ls
zlib-1.2.7-17.el7.x86_64.rpm
steve@linux:/tmp/extractme$ rpm2cpio zlib-1.2.7-17.el7.x86_64.rpm | cpio -ivdm
./usr/lib64/libz.so.1
./usr/lib64/libz.so.1.2.7
./usr/share/doc/zlib-1.2.7
./usr/share/doc/zlib-1.2.7/ChangeLog
./usr/share/doc/zlib-1.2.7/FAQ
./usr/share/doc/zlib-1.2.7/README
365 blocks

Now, when you view the contents of the directory, you see the usr subdirectory has been created, with the files listed above (libz.so.1, ChangeLog, README, etc).

steve@linux:/tmp/extractme$ ls
usr  zlib-1.2.7-17.el7.x86_64.rpm
steve@linux:/tmp/extractme$ ls -lR usr
usr:
total 8
drwxr-xr-x 2 steve steve 4096 Jan 16 16:20 lib64
drwxr-xr-x 3 steve steve 4096 Jan 16 16:20 share
usr/lib64:
total 92
lrwxrwxrwx 1 steve steve    13 Jan 16 16:20 libz.so.1 -> libz.so.1.2.7
-rwxr-xr-x 1 steve steve 90664 Nov  5  2016 libz.so.1.2.7
usr/share:
total 4
drwxr-xr-x 3 steve steve 4096 Jan 16 16:20 doc
usr/share/doc:
total 4
drwxr-xr-x 2 steve steve 4096 Jan 16 16:20 zlib-1.2.7
usr/share/doc/zlib-1.2.7:
total 100
-rw-r--r-- 1 steve steve 73288 Nov  5  2016 ChangeLog
-rw-r--r-- 1 steve steve 16573 Nov 27  2011 FAQ
-rw-r--r-- 1 steve steve  5185 Feb 13  2012 README
steve@linux:/tmp/extractme$ 

You can use this technique to easily extract the contents of an RPM, without having to actually install it anywhere.

-i stands for "copy In", or "extract" as it is more commonly understood.
-v means "verbose".
-d tells cpio to create directories as required.
-m tells cpio to preserve modification times on the files.
--no-absolute-filenames says what it suggests; even if the archive contained an absolute path (eg /etc/shadow rather than ./etc/shadow) then the absolute path would not be followed. This should not be an issue with a genuine RPM, but it is worth adding.

Extracting only some files from the archive

You can also specify a particular file (or pattern of files) that you wish to extract:

steve@linux:/tmp/extractme$ rpm2cpio zlib-1.2.7-17.el7.x86_64.rpm | \ 
    cpio -ivdm "*README"
./usr/share/doc/zlib-1.2.7/README
365 blocks
steve@linux:/tmp/extractme$ 

Extracting Other data from an RPM

You can also extract things like pre- and post- installation scripts from an RPM. The zlib RPM just runs /sbin/ldconfig after install and uninstall:

steve@linux:/tmp/extractme$ rpm -qp --scripts zlib-1.2.7-17.el7.x86_64.rpm
warning: zlib-1.2.7-17.el7.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID f4a80eb5: NOKEY
postinstall program: /sbin/ldconfig
postuninstall program: /sbin/ldconfig
steve@linux:/tmp/extractme$ 

Other packages have more complex scripts. The Apache httpd package creates an "apache" user and group, configures the htcacheclean service, etc:

steve@linux:/tmp/extractme$ rpm -qp --scripts httpd-2.4.6-80.el7.centos.1.x86_64.rpm
warning: httpd-2.4.6-80.el7.centos.1.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID f4a80eb5: NOKEY
preinstall scriptlet (using /bin/sh):
# Add the "apache" group and user
/usr/sbin/groupadd -g 48 -r apache 2> /dev/null || :
/usr/sbin/useradd -c "Apache" -u 48 -g apache \
	-s /sbin/nologin -r -d /usr/share/httpd apache 2> /dev/null || :
postinstall scriptlet (using /bin/sh):

if [ $1 -eq 1 ] ; then 
        # Initial installation 
        systemctl preset httpd.service htcacheclean.service >/dev/null 2>&1 || : 
fi
preuninstall scriptlet (using /bin/sh):

if [ $1 -eq 0 ] ; then 
        # Package removal, not upgrade 
        systemctl --no-reload disable httpd.service htcacheclean.service > /dev/null 2>&1 || : 
        systemctl stop httpd.service htcacheclean.service > /dev/null 2>&1 || : 
fi
postuninstall scriptlet (using /bin/sh):

systemctl daemon-reload >/dev/null 2>&1 || : 

# Trigger for conversion from SysV, per guidelines at:
# https://fedoraproject.org/wiki/Packaging:ScriptletSnippets#Systemd
posttrans scriptlet (using /bin/sh):
test -f /etc/sysconfig/httpd-disable-posttrans || \
  /bin/systemctl try-restart httpd.service htcacheclean.service >/dev/null 2>&1 || :
steve@linux:/tmp/extractme$ 

Conclusion

RPM is a binary file, but it can be manipulated using standard tools. It is really just a CPIO archive with some other metadata around it. It is quite easy to manipulate, without needing to actually install the RPM itself.

 

Invest in your career. Buy my Shell Scripting Tutorial today:

 

Steve Parker - Linux / DevOps Consultant
Share on Twitter Share on Facebook Share on LinkedIn Share on Identi.ca Share on StumbleUpon