linux command not found

Linux Command Not Found: This Will Fix It

Are you using Linux and you have seen the “Command Not Found” error while trying to execute a command? It’s time to find out why.

We will look at this error together and understand how to fix it.

What is the cause of the command not found error?

The “Command not found” error is caused by the fact that Linux is unable to find on your system a command you try to execute. When you run a command Linux looks for binaries in the list of directories specified in the PATH environment variable, this allows you to execute a command without specifying its full path.

In this article we will go through an example of this error and I will show you how to fix it.

You will also understand how Linux (or Unix-like systems) look for commands when a user executes them.

Let’s start!

The PATH Environment Variable

Linux system are configured with a pre-defined set of environment variables required by the operating system to function properly.

The PATH environment variable is one of the most important environment variables in a Linux system. It contains a list of directories used by Linux to search for commands that can be executed without specifying their full path.

You can use the echo command to see the value of the PATH variable:

[ec2-user@localhost ~]$ echo $PATH
/home/ec2-user/.local/bin:/home/ec2-user/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin

In the list of directories inside the PATH you can see the home directory for my current user (ec2-user) but also directories like /usr/bin.

Let’s have a look at some of the commands present in the /usr/bin directory. To restrict the list of commands returned by ls, I just look for commands starting with ch (I use the ch* wildcard to do that):

[ec2-user@localhost]$ ls -al /usr/bin/ch*
-rwxr-xr-x. 1 root root  17488 May 11  2019 /usr/bin/chacl
-rwsr-xr-x. 1 root root 133928 Nov  8  2019 /usr/bin/chage
-rwxr-xr-x. 1 root root  19216 Nov  8  2019 /usr/bin/chattr
-rwxr-xr-x. 1 root root 150528 Apr  9 18:53 /usr/bin/chcon
-rwxr-xr-x. 1 root root 140232 Apr  9 18:53 /usr/bin/chgrp
-rwxr-xr-x. 1 root root  61920 Nov  8  2019 /usr/bin/chmem
-rwxr-xr-x. 1 root root 133952 Apr  9 18:53 /usr/bin/chmod
-rwxr-xr-x. 1 root root 146360 Apr  9 18:53 /usr/bin/chown
-rwxr-xr-x. 1 root root  47816 Nov  8  2019 /usr/bin/chrt
-rwxr-xr-x. 1 root root  14272 May 11  2019 /usr/bin/chvt

Let’s take the chmod command as an example.

If I use the which command to check the full path of the chmod command I get the following:

[ec2-user@localhost]$ which chmod
/usr/bin/chmod

As you can see this is exactly the same directory in the PATH, /usr/bin.

The fact that /usr/bin/ is in the PATH allows us to execute the chmod command withouth having to specify its full path.

Makes sense?

Where Is PATH Defined in Linux?

Wondering where is the PATH environment variable defined?

Let’s find out…

It’s usually defined somewhere in your home directory, and specifically in one of the hidden files used in Linux to configure your user environment: the .bashrc file.

In Linux, the dot before the name of a file means that the file is hidden. It’s not visible if we execute the ls command without flags. It’s only visible if you pass the -a flag to the ls command.

The .bashrc file is actually a shell script that gets executed when Linux initialises an interactive shell. This allows you to configure your environment the way you want every time you open your shell.

If I look at the .bashrc file on my system I see the following lines:

# User specific environment
PATH="$HOME/.local/bin:$HOME/bin:$PATH"
export PATH

As you can see the PATH variable is defined and it’s then made available to any child processes of this shell using the export command.

If you want to add another directory to the PATH you can simply update the .bashrc file.

This is a common requirement if you download external tools that are not part of the Linux operating system and you want to be able to execute them from your shell without having to specify their full path.

One common scenario is adding Java to the Linux PATH after downloading the JDK (Java Development Kit) on your system.

PATH Configured At System-Wide Level

When I see the value of the PATH variable on my system, here’s what I get:

/home/ec2-user/.local/bin:/home/ec2-user/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin

There’s something that doesn’t make sense to me…

…in the .bashrc file in the home directory on my user I only see:

PATH="$HOME/.local/bin:$HOME/bin:$PATH"

So, where do the following directories come from considering that they are not in my user’s .bashrc file?

/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin

They must be defined somewhere at system level and not just at user level.

In Linux, system-wide configuration files are located under the /etc directory. For example in /etc/bashrc.

Let’s find out where this initial value for the PATH comes from using a recursive grep as root under the /etc directory.

[root@localhost]$ grep -r PATH /etc/* | grep "/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin"
/etc/ssh/sshd_config:# This sshd was compiled with PATH=/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin

The only result is in the configuration file for the SSH deamon. According to a comment in this file, the daemon is compiled with the PATH set to the value I’m seeing on my system.

That’s where the value of the PATH comes from!

How Do I fix the Bash error “command not found”?

So far we have seen what the PATH is…

…but how does it help us fix the command not found error?

First of all, before looking at how the command not found error could be related to the PATH, let’s look at a simple cause.

Before doing any other checks make sure you are not misspelling the command when you execute it.

This might be happening mostly to those who are new to Linux and are learning the commands.

If the way you have typed the command is correct, then keep going…

The next reason could be that the directory where the command is located is not in the PATH and there could be two reasons for that:

  1. The command is available on the system but its directory is not in the PATH.
  2. The command is not available on the system at all.

Scenario 1 can occur if you download a specific tool on your Linux system and you don’t add the directory in which the binary is located to the PATH environment variable.

To update the value of the PATH you have to modify the .bashrc file.

Let’s say the current value of the PATH is:

PATH="$HOME/.local/bin:$HOME/bin:$PATH"

And I want to add the directory /opt/install to it because that’s where the command I want to execute is located. That line would become:

PATH="$HOME/.local/bin:$HOME/bin:$PATH:/opt/install"

The order of the directories in the PATH is important, the first directory has higher priority than the second directory, and so on.

So, if you want the /opt/install directory to be the first one to be searched when a command is executed the PATH definition becomes:

PATH="/opt/install:$HOME/.local/bin:$HOME/bin:$PATH"

Notice the dollar $ in front of PATH. This is REALLY important because it refers to the existing value of the variable PATH.

Omitting the $ sign in this line could have catastrophic effects on your system. That’s because the shell wouldn’t know anymore where to find basic commands like ls, cd, vim, etc…

In the next section we will look at the scenario 2, where the command is not available on your Linux system.

Running a Command Not Available on the System

Now, let’s have a look at what happens when we execute a command that is not available on a Linux system.

I take, for example, the rsync command:

[ec2-user@localhost ~]$ rsync
-bash: rsync: command not found

How do I know if I’m seeing the “command not found” error because the rsync command is not in the PATH or because it doesn’t exist on the system at all?

I can use the package manager of my Linux distribution. In this case I’m using CentOS and hence I will use the yum command to see if the rsync package is installed:

yum list --installed | grep rsync

This command doesn’t return any results, this means rsync is not available on the system.

Another option is to use the RPM command to query the RPMs installed on my Linux system:

rpm -qa | grep rsync

Once again, no results for the rsync package.

So, let’s install it!

The yum search command returns a result for rsync:

[ec2-user@localhost ~]$ yum search rsync
Last metadata expiration check: 1 day, 4:15:26 ago on Sun 19 Jul 2020 05:12:46 PM UTC.
=================================== Name Exactly Matched: rsync ===================================
rsync.x86_64 : A program for synchronizing files over a network

And we can install the rsync package using the “yum install” command:

[ec2-user@localhost ~]$ sudo yum install rsync
......
....

Installed:
  rsync-3.1.3-7.el8.x86_64

Complete!

And now if I try to execute the rsync command again to check its version:

[ec2-user@localhost ~]$ rsync --version
rsync  version 3.1.3  protocol version 31
Copyright (C) 1996-2018 by Andrew Tridgell, Wayne Davison, and others.
Web site: http://rsync.samba.org/

The command works well!

Conclusion

In this guide we have seen three possible scenarios in which the “command not found” error can occur on Linux when we execute a command:

  1. We have misspelled the command.
  2. The command is available on the system but its directory is not in the PATH.
  3. The command is not available on the system.

I have also explained how the PATH environment variable works and how important is for a Linux system.

Have you managed to find what’s causing this error in your system?

Let me know in the comments below! 🙂

Share knowledge with your friends!

Leave a Reply

Your email address will not be published. Required fields are marked *