If you want to help people,
keep it simple!

Overcome Command-Not-Found errors (once and for all)

No - I don’t have any empirical data for this. But …

if I should name the top 5 frustrations of Linux beginners, then the “command-not-found” errors would be most certainly on this list.

Especially if you are new to the Linux command line, it’s not always obvious what is causing this error.

First: You simply don’t know all the tools

As you start exploring the Linux command line (aka “the Linux shell”), you simply don’t yet know the tools that are available there.

There are a load of them and unfortunately not every tool is available on every Linux distribution. And don’t worry - you will get to know them step-by-step once you proceed through your Linux journey.

(I’ll show you a shortcut for getting all the really essential tools later on - but that’s _not_ the point of this post at all)

The point here is …

The shell searches in it’s own way …

To understand (and really overcome) these “command not found” errors, we need to understand what causes them, don’t we?

So let’s face the challenge and let’s have a look how the shell searches for a command to run.

Everything starts with cutting the command line you have entered into pieces.

For illustration let’s take a look at this simple example:

ls -l /etc

No matter what this command line is all about - but before doing anything, the shell cuts it into pieces separated by one or more spaces.

Sounds simple and obvious? Yes … but go on and follow me a little further with the explanation … I’ll get to the point soon.

So the shell separates the command line into pieces

… and takes the first part of it as the command that should be run.

And here it becomes interesting:

The shell now has multiple options what the command to run could be.

And it analyses the options it has in a strict order:

Options for types of commands in their order of execution

  • Shell Built-In
  • Alias
  • Function
  • Search for an executable file somewhere in the directory tree

Let’s go through these steps one-by-one …

Shell Built-Ins

As the name says - shell built-ins are commands that are built directly into the shell. The shell directly knows what to do to accomplish the given task.

An example for this would be

echo Hello World

for simply printing out these two words to the console.

Sidenote: Have you ever heard that a Linux system gives you multiple options for the type of shell to run for you (bash, dash, korn-shell, busybox, …)? These built-in commands are one characteristic that differentiates them.


If the shell doesn’t know a command by itself, an alias can be used to tell the shell what to do.

Many systems for instance have an alias defined, that allows you to run the command “dir” instead of typing in “ls -l”.

alias dir="ls -l"

In this way - if you type in “dir” as the command - the shell knows that “dir” has to be substituted with “ls -l” and the interpretation of the command line starts from the beginning.

Wanna see all aliases currently available within your shell?

Call the command “alias” without any additional parameter …


As we don’t want to start scripting just yet, let’s keep it simple for now:

Imagine a function as an alias “on steroids”.

A function names a new command, that can consist of multiple command lines, control-structures and you can even give parameters to them.

But for now - take a function as an on-the-fly defined new command within the shell.

(if you wanna see all functions, have a look at the output of the command “set”. But be warned - this output can be huge)

Search for an executable file somewhere in the directory tree

And this is where all the trouble most of the time comes from …

If the command you addressed is neither a shell built-in, nor an alias or a function, then the shell has to search for the command by itself.

Now the command needs to be an somehow executable file somewhere within your filesystem.

To help the shell find a named executable file as fast as possible, the shell is given a list of directories where to search in.

And this list is given to the shell via the variable $PATH

The content of this variable could look like this:


Given this list, the shell now searches these four directories for an executable file with the name of the command that shall be started.

With the example above given, it first looks into the directory “/bin”, then into “/sbin”, then into “/usr/bin” and lastly into “/usr/sbin” … exactly in this given order.

Did you notice anything here?

Isn’t there a directory missing where to search for?

No? But! The current directory is missing!

Yes - the shell never looks additionally into the directory you are currently in.

Imagine: You are within a directory, you see this executable file via “ls”, but the shell still pretends not to see a command with this name and throws an annoying “command-not-found” error …

Then this is because

the shell really only searches for files within the listed directories in $PATH.

following exactly the given order.

That doesn’t mean that you cannot start executables from other directories.

But you have to avoid the searching.

Simply give the shell the path to the executable - so the shell can execute it without doing the predefined search-thing.

You have a script called “setup.sh” within your current directory? And this directory is “/home/hector”?

Run it by explicitly addressing the script with its path:


If you are currently within this directory, then you can simplify this command line by simply calling


as the directory “.” always addresses the current directory.

At the end - let me give you two tools at hand:

type … this command tells you, if the command name you give it as a parameter is a “shell built-in”, an alias, a function or an executable file within $PATH

drwho@demo:~$ type echo
echo is a shell builtin

which … this command searches all directories in $PATH in the given order and tells you if and where the given command can be found

drwho@demo:~$ which ls

Here is what to do next


If you followed me through this article, you certainly have realized that knowing some internals about how things are working at the Linux command line, can save you a lot of time and frustration.

And sometimes it’s just fun to leverage these powerful mechanics.

If you wanna know more about such “internal mechanisms” of the Linux command line - written especially for Linux beginners

have a look at “The Linux Beginners Framework”

In this framework I guide you through 5 simple steps to feel comfortable at the Linux command line.

This framework comes as a free pdf and you can get it here.

Wanna take an unfair advantage?


If it comes to working at the Linux command line - at the end of the day it is always about knowing the right tool for the right task.

And it is about knowing the tools that are most certainly available on the Linux system you are currently on.

To give you all the tools for your day-to-day work at the Linux command line, I have created “The ShellToolbox”.

This book gives you everything

  • from the very basic commands, through
  • everything you need for working with files and filesystems,
  • managing processes,
  • managing users and permissions, through
  • hardware analyses and
  • simple shell-scripting to the tools you need for
  • doing simple “networking stuff”.

Everything in one single, easy to read book.

With explanations and example calls for illustration.

If you are interested, go to shelltoolbox.com and have a look (as long as it is available).