This site is now 100% read-only, and retired.

Replacing binaries with dpkg-divert

Posted by Steve on Wed 6 Apr 2005 at 19:36

One of the strengths of the Debian system is the way in which it deals with having multiple similar packages installed, and allowing you to choose which one you use.

We already discussed one way in which Debian allows you to choose a specific package from a number of available options in the piece using the Debian alternatices system.

Another possibility is to replace a binary installed from a package with one of your own choosing, Debian allows this via the use of the dpkg-divert command.

The dpkg-divert command allows you to replace a binary installed upon the system, and have this replacement persist even if you upgrade packages.

One common reason to do this is if you're using a mailserver such as qmail, and you wish to replace the file /usr/lib/sendmail with the version from that package. In this case making a diversion is a good solution.

Another example where you might wish to replace a package's binary is in the case of the gcc, or g++, compiler commands.

Assuming that you were keen on rebuilding Debian packages and wished to ensure that some optimizations were applied. Rather than patch the Makefile, or build scripts you could just replace the compiler command to ensure that your options were applied globally.

(This is what the pentium-builder package does, incidently).

To replace a packages binary you have to:

  • Rename the file that you're replacing.
  • Add the diversion to the system.

Both these steps can be achieved with one command. For example assume we wish to replace the gcc command to cause it to add "-O2" to all compilation jobs we'd run the following command as root:

dpkg-divert --add --rename --divert /usr/bin/gcc.real /usr/bin/gcc

This adds a diversion to the file /usr/bin/gcc, causing that binary to be renamed to /usr/bin/gcc.real.

Now whenever we upgrade the gcc package the system will know that it shouldn't overwrite the gcc binary, instead the new package will have it's binary installed as gcc.real.

Now that we've done that we can create a simple shell script with the name gcc which will add our option, and invoke the real compiler:


/usr/bin/gcc.real -O2 $*

This script invokes the real compiler, with all the options we've been passed and the new option "-O2".

If we wish to remove this diversion at a future point in time we can use:

# Remove the script we added
rm /usr/bin/gcc     

# Remove the diversion, renaming /usr/bin/gcc.real back to /usr/bin/gcc
dpkg-divert --rename --remove /usr/bin/gcc

You can also list all the diversions which you have currently installed with:

dpkg-divert --list



Re: Replacing binaries with dpkg-divert
Posted by Anonymous (194.138.xx.xx) on Thu 5 May 2005 at 14:27
This is a GREAT asset to the (by my knowledge) dormant (and hopefully not dead) debtoo project.

OTOH, inserting USE flags in this way seems like a hackish solution, but as long it gives some means to make "from source" debian aka debtoo, is ok with me.

[ Parent ]

Re: Replacing binaries with dpkg-divert
Posted by jae (84.163.xx.xx) on Fri 9 Dec 2005 at 06:56
Very annoyingly, and frustratingly, there's an old (nay, ancient) bug in dpkg-divert... --rename across filesystems fails. Oldest report is 4 1/2 years old. Includes patch even. Still unfixed, not even commented on.

Yes, Debian's great, except when it's not...

[ Parent ]

"$@" vs $*
Posted by darkonc (24.80.xx.xx) on Thu 26 Jan 2006 at 23:57
When using a shellscript to replace a command, you should almost always use
/usr/bin/gcc.real -O2 "$@"
instead of
/usr/bin/gcc.real -O2 $*
$* can defeate quoting of parameters with spaces and globs in them... I.e. if you have a file "simple program.c", "$@" will pass it on properly, while $* will result in two parameters -- 'simple' and 'program.c'.
This becomes more of a problem as code is exchanged with the windows and mac universes where spaces in filenames are more common.

[ Parent ]

Re: "$@" vs $*
Posted by Anonymous (82.43.xx.xx) on Wed 31 Oct 2007 at 08:08
Phew! - you saved me having to comment - that is an important one.

[ Parent ]

Re: Replacing binaries with dpkg-divert
Posted by Anonymous (59.167.xx.xx) on Sat 24 Jun 2006 at 01:38
It would be helpful to explain why all the arguments are necessary. For example,

--add --rename --divert

What are the different permutations? ie, what else can the tool do?

[ Parent ]

Re: Replacing binaries with dpkg-divert
Posted by Steve (62.30.xx.xx) on Sat 24 Jun 2006 at 01:42
[ View Weblogs ]

You're probably right. Although reading the manpage will show you all the arguments and what they do. I'll bear it in mind for future articles.


[ Parent ]