Which is the best practice when replacing a system binary

directory-structureosxpackage-managementpath

I'm working on Mac OS X which is shipped with several binaries mostly located in /usr/bin/ and /usr/sbin/. Since it doesn't have a native package manager like some Linux distros, I got used to managing my own binaries, building and installing in /usr/local/<package_name>/.

This way, I am able to fully remove a package from my system at the cost of manually update the PATH and the MANPATH variables in the .bashrc file.

Here is a simple example:

Mac OS X ships with ant 1.7.0, located in /usr/bin. I need to use the latest version, so I download it from Apache and then unzip (build) it to /usr/local/apache-ant-1.8.2. Then I update my .bashrc file with:

# Mac OS X original PATH
PATH="/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/X11/bin"
# Apache Ant 1.8.2
PATH="$PATH:/usr/local/apache-ant-1.8.2/bin"
export PATH

I make sure to export the /usr/bin/ and /usr/sbin/ before the ant/bin/ because there are often other binaries besides the ant that I don't want to override.

The problem is that when I type which ant I get /usr/bin/. So I rename the /usr/bin/ant to /usr/bin/ant-old in order to work with the latest build.

While this works, I want to know if there are better approaches to replacing a system binary (mainly to avoid the last rename).

Best Answer

Replacing a system binary should be a last resort.

My advice is to:

  • Put /usr/local/bin ahead of /usr/bin and other system directories on the PATH.
  • Make /usr/local/bin/ant a symbolic link to /usr/local/apache-ant-1.8.2/bin/ant.
  • Don't include /usr/local/apache-ant-1.8.2/bin in the PATH at all.

This way:

  • Your customizations (in /usr/local/bin) override the system defaults.
  • The symbolic link /usr/local/bin/ant reminds you where you got that version of ant.
  • If you want to test something with the default setup, just remove /usr/local/bin from your PATH for the duration of the test.
Related Question