Shell – Use alternatives or adding to PATH

pathshellsoftware installation

I'm a bit confused about the proper way to make a script globally available from the terminal, like a command. There are two ways, using the alternatives utility, basically making a symlink to /usr/bin, and adding to PATH. I understand that adding to PATH means adding the complete directory, and it may work on per-user basis. But what I don't like is the messy-ness of the process. It looks (at least from my POV) that every distro has it's own quirks, and even different versions of them give me trouble with adding something to the PATH, and then there are answers on the web arguing how to do it, or even more important, how NOT to do it.

When installing Java I would usually find instructions on using alternatives to make java and javac globally available, like this:

alternatives –install /usr/bin/java java /opt/jdk1.7.0_79/bin/java 2

Now, what is wrong with using alternatives more often, and I find it mostly in those Java setup tutorials? I use it to set up the Typesafe Activator as globally available. I also find it easier for automation tools such as Ansible. Is there something wrong from an administrator point of view?

Best Answer

First, alternatives is from debian and will not work in redhat, freebsd or many other systems. Second, the standard recommendation is to use /usr/bin for vendor packages, /opt for third party packages, /usr/local/bin for local executables and set the path for user executables.

alternatives is intended where you can have multiple packages provide the same functionality, for example there are at least three mailx packages, two awk packages and multiple java packages available in debian.

Now to the meat of the matter: why do the tutorials use alternatives like you show? Because alternatives is used closely with debian packaging this allows a thirdparty package to mostly act like a vendor package. Should you use alternatives instead of install? Absolutely not, alternatives does not set permissions.


One of the core ideas in unix is that everything is a file. (This is not strictly true any more, if it ever was but it as a design goal shaped many things.) now there are three things you can do with a file that are associated with permissions. They are read, write and execute. When reading or writing there are two ways to specify a file to open. They are absolute path (the path relative to the root directory) or relative path (the path relative to the current directory). Executing is a little more complicated in that there are three ways to specify the file to be executed. They are absolute path, bare filename and relative path. The absolute path is the same as above. the relative path is similar to above but is only used if explicitly specified (the name includes a slash) or the path includes a relative path. The path is specified per process in the PATH environment variable (which is inherited from the parent process during a fork). The path is a list of directories to look in to find an executable when the executable is specified without a slash in the name. To simplify administration (and speed locating of executables) the executables are collected into a small number of directories. Most executables are in either /bin, /usr/bin, or /usr/local/bin with special purpose executables placed in /sbin, /usr/sbin, /usr/local/sbin and /usr/games. Some users will have additional binaries placed in other locations for their personal use. I like to place mine in ~/.bin but ~/bin is also common and other directories are sometimes used as fits the user.

When placing executables to be shared each user can tell other users where the binary is or put it in a common location. When putting executables in a common location you can either copy the file and set its permissions by hand or use install which will take care of the details in a simpler fashion. Sometimes you install complicated third party packages and don't want them cluttering up the main parts of the filesystem with all the related files (libraries, etc) and put them in /opt/package or /opt/vendor/package. You could add the relevant directory to the path, or place a wrapper script or symbolic link in a standard directory. alternatives places a symbolic link and a database entry so that when you have more than one program available that has the same basic functionality and the same executable name, the right one is used.

Related Question