The Linux which command basically identifies the executable binary that launches when you issue a command to the shell. In case you have different versions of the same program on your computer then you can use which Command on Linux to find out which one the shell will use.

Binaries and Paths

When you try to run a program or command from the terminal window, the shell which is usually, Bash on modern distributions has to find that command and launch it.

Some commands like cd, history, and pwd, are built into the shell, so Bash will not have to work too hard to find these.

But how does Bash locate other commands, programs, and external stand-alone binaries? Well, in that case, Bash uses the path, which is actually a collection of paths, each of which points to a directory.

The base then searches each of those directories for an executable that matches the command or programs you are trying to run. When it finds one, then Bash launches it and abandons the search.

You can also use echo to check the $PATH environment variable and see the directories in your path. To do so, you have to type the following, and then hit Enter:

echo $PATH

The output list will separate each path with colons (:). On the system we are using, Bash will search the following directories in this order:

/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin
/user/games
/usr/local/games
/snap/bin

There are many folders that are called /sbin and /bin in the file system, which can lead to little confusion.

Related:  How to Turn On Dark Mode in Windows 10 And Relax Your Eyes

Watch Those Paths

Let us say we have an updated version of a program known as htg. It is in our current directory, and we can run it by typing the following command:

./htg

Though it is not much of a program, it just prints the version number and then closes down. The newer version is 1.2.138.

To run a program in the current working directory, you have to type “./” in front of the program name, so Bash knows where to find it.

Because we want to run this particular program from any directory so we are going to move the executable into the /usr/bin directory. Bash will find that program in the path and then run it for us.

We do not need the executable in our current directory, nor do we need to type “./” in front of the program name, as shown below:

sudo mv htg /usr/bin

Now, let us try to run the program by typing:

htg

Something runs, however it is not our new, updated program. Rather, it is the older version, 1.2.105.

The which Command

The issue we demonstrated above is why which command was designed.

In this example, we will use which and pass the name of the program which we are investigating as a command-line parameter:

which htg

which reports it is found a version of htg in the /usr/local/bin directory. Due to that location appears in the path before the directory to which we moved the updated htg, Bash uses that earlier version of the program.

But, if we use the -a (all) option as shown below, which continues to search even if it finds a match:

which -a htg

It then lists all of the matches in any of the directories in the path.

Related:  Microsoft is Finally Working On a Modern Windows 10 File Explorer

So, that is the problem, there is an earlier version of the program in a directory that’s also in the patch. Also, that directory is being searched before the directory in which we dropped the new version of the program.

To verify, we can simply type the following and explicitly run each version of the program:

/usr/local/bin/htg
/usr/bin/htg

This explains the problem, and the solution is very simple.

Actually, we have options. We can either delete the old version in the /use/local/bin directory or we can move it from /usr/bin to /usr/local/bin.

Watch Those Results

Two results do not necessarily mean two binary files.

Let’s look at an example in that we will use the which command with the -a (all) option and look for versions of the less program:

which -a less

which reports two locations that house a version of the less program, but is it true? It would be really odd to have two different versions (or the same version in multiple locations) of less installed on a Linux computer.

So, we are not going to accept the output from which. Instead, we will dig a bit deeper.

We can use the ls, -l (long listing), and -h (human-readable) options to see what is really going on:

ls -lh /usr/bin/less

The file size is reported as nine bytes! and that’s definitely not a full copy of less.

The first character of the listing is an “l.” A normal file will have a hyphen (-) as the first character. The “l” is a symbol that means a symbolic link.

Related:  Apple Warns of iOS 13 Bug Giving Access to Third-Party Keyboard Apps

In case you missed that detail, the –> symbol also indicates this is a symbolic link, which you can think of as a sort of shortcut. This one point is to the copy of less in /bin.

Let us try again with the version of less in /bin:

ls -lh /bin/less

This entry is obviously a “real” binary executable. The first character of the listing is a hyphen (-), that means it is a regular file, and the file size is 167 KB.

So, only one copy of less is installed, however, there’s a symbolic link to it from another directory, which Bash also finds when it searches the path.

Checking Multiple Commands at Once

You can simply pass multiple programs and commands to which, and it will check them in order.

For example, if you type:

which ping cat uptime date head

which works through the list of programs and commands you supplied it with and lists the result for each one.

Which, which is which?

If you are so inclined toward then you can also use which on itself by typing the following:

which which

Apart from poking around the Linux file system out of curiosity, which is most useful when you expect one set of behaviours from a command or program, but will get another.

You can also use which in these cases to verify the command Bash is launching is the one you want to use.