A lot goes on behind the scenes when you run a Linux program. The PATH variable can make this more convenient, but you need to use it carefully.
What Happens When I Run a Command?
When you run a command in your terminal, Linux carries out a few checks to decide how to act. It may detect that you’re running an alias, in which case it will substitute what you typed for another command. It may recognize the name of a shell function, which it then proceeds to run. Or your command may be built into the shell itself.
In most cases, however, the command you type is the name of a file, either a binary executable or a script in an interpreted language. These files are usually in a bin directory, often one of:
- /bin
- /sbin
- /usr/bin
- /usr/local/bin
You can type the path of a program, either relative or absolute, and your shell will run it. For example:
/bin/ls -l *.md/usr/bin/date
However, this isn’t very convenient, so Linux uses a shortcut called the PATH environment variable. This is a set of directories that Linux will search to locate files when it tries to run a command. On my system, my PATH looks like this:
This means, if I try to run a command called “program,” Linux will look for a file at /usr/local/sbin/program to run. If that file doesn’t exist, it will look for a /usr/local/bin/program file, and so on.
In the PATH, directories are separated by the colon character (:) and you can list them in a more readable form using tr:
So, given that there is an executable file named “ls” in the directory /bin, which is in the PATH variable, typing ls will cause the shell to run the program at /bin/ls.
You might expect to be able to run programs in your current directory, especially if you came to Linux from MS-DOS. But your PATH probably doesn’t include your current directory by default, so you won’t be able to do so just by typing the command’s name.
This is a bit counterintuitive since you’re used to other commands operating on files in your working directory using just their name. For example, a command like ls README.md will list the README.md file in your current directory, if there is one.
This is a totally different case to running a program in your current directory. Passing the ls command the name of a file hands off responsibility to that program. The ls program then inspects the command-line argument, recognizes it as the name of a file in the current directory, and lists it.
So Why Isn’t . in My PATH?
Wouldn’t it be great if you could run programs in your current directory without having to type their pathname each time? It’s not too much of an overhead, but if you’re writing your own programs or scripts, you could end up running them time after time, so any efficiency savings seem like a good thing.
While it may seem magical, simply adding the current directory symbol to your PATH will let you do just that:
This seems better than not being able to run commands in your working directory, so why isn’t it the default? I’ve worked with systems before where it was the default, but this isn’t universal—for good reason.
For a start, adding your working directory to the beginning of your PATH can result in other programs hijacking standard commands. Take this example:
In this case, you would expect the standard find program—which happens to be in /usr/bin on my system—to run and list all C files underneath /tmp. But /tmp is a shared directory; what if another user creates an executable file in that directory and names it “find”?
In this case, you’re unintentionally running someone else’s program under your own user account—a potential recipe for disaster!
There’s always a risk when you run a command using just its name because you can’t be quite sure what your shell is actually going to do. But adding the current directory to your PATH increases this risk. You’ve turned a set of well-known, presumably safe locations into one with a variable location that could, potentially, be unsafe.
You can help to reduce this risk by adding the current directory to the end of your PATH instead:
Now, even with a find program in your working directory, your shell will pick up the executable in /usr/bin and run that instead. This is a bit safer, but it flips the problem back around: if you’re working on a program named find in your local directory, you’ll need to run it by typing ./find each time. You’ve gained a bit of convenience, but it’s unpredictable.
The other reason to keep . out of your PATH is similar: it’s easy to cause problems with typos. Imagine you’re trying to run the ls command but accidentally type ks instead and there’s a ks program in your current directory. Running a program should be predictable. Thanks to the relatively well-controlled locations that are usually in your PATH, you should rarely run anything you don’t intend to.
How Do I Add My Current Directory to my PATH?
With a full understanding of the risks and benefits, you may decide you still want your working directory in your PATH. That’s fine, so long as you’re careful and you know what you’re getting into.
You’ll want to set your PATH permanently in a startup file like .bashrc, .profile, or .zshrc. The exact file will depend on your environment, but ~/.bashrc is probably the most common location.
Edit the appropriate file and add a line like this:
export PATH=$PATH:.
This adds your current directory to the end of your path, so programs in /bin and other common locations will still run first. If you want your current directory to take priority, add it at the beginning:
export PATH=.:$PATH

Related
And How Do I Run Programs in My Current Directory?
If you choose not to add your current directory to PATH, don’t worry; you can still run any program on your file system, as long as you have permission to.
Say you have a program somewhere in your home folder, like:
/Users/bobby/repos/cloc/cloc
Because it’s not in a path directory, you won’t be able to run it just by typing its name:
Instead, just supply a path—either absolute or relative—to this executable file:
Using the path to a command instead of its name will bypass any PATH lookup. Be sure to always check you are running the program you think you are.
This second version uses the period character (“.”) to represent the current directory. Once the shell expands it, this command will be the equivalent of the full-path version. But the “.” will always be relative to your current working directory.