El Linux which
command identifies the executable binary that is started when a command is sent to the shell. If you have different versions of the same program on your computer, you can use which
to know which one the shell will use.
Binaries and paths
When you try to run a program or command from the terminal window, el shell (generally, Tried in modern distributions) you have to find that command and run it. Some commands, What CD, history, and pwd, are built into the shell, so Bash doesn't have to try too hard to find them.
But, How does Bash locate other commands, independent external binaries and programs? Well, Bash uses the path, which is actually a collection of routes, each of which points to a directory. Then it looks in each of these directories for an executable that matches the command or program it is trying to execute.. When you find one, Bash throws it and abandons the search.
You can use echo
to check the $PATH
environment variable and see the directories in your path. To do it, type the following and then press Enter:
echo $PATH
The output list separates each route with a colon (:). On the computer 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 called /sbin
and /bin
in the file system, which can cause some confusion.
Look at those roads
Let's say we have an updated version of a program called htg
. It is in our current directory and we can run it by typing the following command:
./htg
Not a great show, it just prints the version number and then closes. The new version is 1.2.138.
To run a program in the current working directory, must write “./” delante del nombre del programa, so Bash knows where to find it.
Because we want to run this particular program from any directory, let's move the executable to /usr/bin
directory. Bash will find that program on the path and run it for us.
We don't need the executable in our current directory, ni necesitamos escribir “./” delante del nombre del programa, as it's shown in the following:
sudo mv htg /usr/bin
Now, Let's try to run the program by typing:
htg
Something runs, but it is not our new and updated program. Rather, is the previous version, 1.2.105.
The one who command
The problem we previously demonstrated is why which
command it was designed.
In this example, we will use which
and pass the name of the program we are investigating as a command line parameter:
which htg
which
reports that it has found a version of htg
at /usr/local/bin
directory. Because that location appears in the path before the directory we moved the update to htg
, Bash uses that older version of the program.
Despite this, if we use the -a
(everything) option as shown below, which
continues searching even if it finds a match:
which -a htg
Then it lists all the matches in any of the directories in the path.
Then, that's the problem: there is an older version of the program in a directory that is also in the patch. And that directory is searched before the directory in which we drop the new version of the program.
To verify, we can write the following and explicitly run each version of the program:
/usr/local/bin/htg
/usr/bin/htg
This explains the problem and the answer is simple.
Actually, we have options. We can remove the previous version in the /use/local/bin
directory or move it from /usr/bin
for /usr/local/bin
.
Look at those results
Two results do not necessarily mean two binary files.
Let's look at an example where we will use the which
command with the -a
(everybody) and look for versions of the less
Program:
which -a less
which
reports two locations that host a version of the less
Program, but is that true? It would be strange to have two different versions (or the same version in multiple locations) from less
installed on a Linux computer. Then, we will not accept the departure of which
. Instead, let's dig a little deeper.
We can use the ls
, -l
(long list), and -h
options (human readable) to see what is happening:
ls -lh /usr/bin/less
The file size is reported as nine bytes!! It is definitely not a complete copy of less
.
The first character in the list is a “l”. A normal file would have a dash (-) as first character. The “l” es un símbolo que significa symbolic link. If you missed that detail, the -->
The symbol also indicates that it is a symbolic link, which you can consider as a kind of shortcut. This one points to the copy of less
on /bin
.
Let's try again with the version of less
on /bin
:
ls -lh /bin/less
Esta entrada es por lo visto un ejecutable binario “real”. The first character in the list is a hyphen (-), which means it is a normal file and the file size is 167 KB. Then, just a copy of less
it's installed, but there is a symbolic link from another directory, that Bash also finds when searching the path.
RELATED: How to use the ls command to list files and directories in Linux
Checking multiple commands at the same time
You can pass various programs and commands to which
, and will review them in order.
As an example, yes write:
which ping cat uptime date head
which
cycles through the list of programs and commands you provided and lists the result of each.
Which which is which?
If you wish, you can also use which
about himself writing the following:
which which
While poking around the Linux file system out of curiosity, which
is most useful when you expect a set of behaviors from a command or program, but get another.
You can use which
in these cases, to verify that the command you are launching Bash is the one you want to use.
setTimeout(function(){
!function(f,b,e,v,n,t,s)
{if(f.fbq)return;n=f.fbq=function(){n.callMethod?
n.callMethod.apply(n,arguments):n.queue.push(arguments)};
if(!f._fbq)f._fbq = n;n.push=n;n.loaded=!0;n.version=’2.0′;
n.queue=[];t=b.createElement(e);t.async=!0;
t.src=v;s=b.getElementsByTagName(e)[0];
s.parentNode.insertBefore(t,s) } (window, document,’script’,
‘https://connect.facebook.net/en_US/fbevents.js’);
fbq(‘init’, ‘335401813750447’);
fbq(‘track’, ‘PageView’);
},3000);