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: