How to add more directiories in PATH

20,188

Solution 1

In Unix certain environment variables, such as $PATH are special in the sense that they're a list of items, not just a single item. With these types of lists, a colon (:) separates the items in the list.

For $PATH you can see this if you merely print it:

$ printenv PATH
/sbin:/bin:/usr/sbin:/usr/bin

If you want to add additional items to this, you have to include the previous list plus the new item. That's effectively what you're doing when you say PATH=$PATH:<new item>.

$ PATH=$PATH:/path/to/some/dir
$ printenv PATH
/sbin:/bin:/usr/sbin:/usr/bin:/path/to/some/dir

Keep in mind that these changes are local only to the shell where you ran them. If you want your changes to $PATH to persist between reboots, or show up in other instances of your shell, you need to add them to a configuration file so that they'll get setup as part of your defaults.

Typically for user's this is what you'd do to these files ~/.bashrc & ~/.bash_profile:

export PATH=$PATH:$HOME/bin:$HOME/somedir

Adding a line such as this will modify your $PATH.

Alternative to $PATH usage

If you'd simply like to be able to run scripts and executables that are not in your $PATH that can be easily solved by using this method instead of adding to $PATH.

Here's a scenario, lets say we have an executable such as this:

$ ls -l helloexec.bash
-rwxr-xr-x 1 user1 user1 31 Aug 12 07:45 helloexec.bash

But it's not on the $PATH so we cannot run it:

$ helloexec.bash
bash: helloexec.bash: command not found...

So you're thinking, oh, I have to add it to my $PATH to be able to run it. But instead, you can run any executable that's in the current directory like so:

$ ./helloexec.bash
hello bash

In Unix type operating systems, it's imperative that you internalize this method of interacting with your scripts and executables, rather than insist that they all be on the $PATH.

Dangers of adding to $PATH

In your examples you show that you'd like to add ~ to your $PATH. I've seen many users do this over the years, or want to, thinking that it'll be a huge convenience & time saver to just put this directory, directly on their $PATH.

This is typically not a good approach to things. Rather, you should think long and hard about where you want to store executables in Linux/Unix, and only add directories that are critically necessary to have such a prominent place such as being on $PATH.

Most will typically add the system directories, and then add a $HOME/bin to the $PATH and leave it at that. Putting more things on the $PATH can lead to unintended consequences such as commands not working as expected or even worse, creating a situation that allows a system to be more easily compromised.

For example, say you downloaded some script from a website, and hadn't realized that your web browser was changed to save files to $HOME. This downloaded file, is now in a position that it can be invoked by a would be attacker.

Alternatively if you have the order of your $PATH in such a state that ~ comes before other directories, such as something like this:

$ printenv PATH
/home/vagrant:/sbin:/bin:/usr/sbin:/usr/bin

And we accidentally downloaded an executable such as this:

$ cat ps
#!/bin/bash

/bin/ps -eaf | grep -v "spyware"

Now when someone runs ps, they're using this version and not the intended /bin/ps.

Solution 2

PATH is an environment variable that contains the current value for PATH on your system, which is all the directories that will be searched for the executable if you type the name of the executable in without a relative or absolute location for it.

For example, if you want to execute something in the current directory ./something will work because the '.' says that something should be found in the current directory. The shell knows then at the executable should be found relative to the current directory. More info in askubuntu. You could also use ./somedirectory/something. The point is the directory structure entered doesn't start at the root (/).

An absolute location would look like : /home/flerb/something, it starts from the root directory.

Using $, $PATH is expanded on the command line when you enter the command and is replaced by its contents, for example echo $PATH might give something like:

$echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin

(You can check the current state of your environment variables with env on the command line)

Tilde as described in the Bash Reference Manual is actually replaced by the HOME environment variable in most situations, see the reference manual if you want to learn about tilde weirdness that I had no idea about. How we're using tilde, it equals:

$ echo ~
/home/flerb

$ echo $HOME
/home/flerb

Because of this, if your path was as is shown above, if you enter:

(As an aside, why you should quote expansions)

PATH="$PATH":"$HOME"

or

PATH="$PATH":~

The shell expands it to:

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/flerb

HOME is appended to the end of PATH and you don't replace your entire PATH with just your home directory, which would cause some problems.

Aside

'.' is a link to the directory that you are in. I include these links for completeness, as pointed out by RalfFriedl, . is a shell builtin that gets its meaning from the filesystem. If you ever see . and .. in the output of ls -al and wonder what they are:, What is (.) and (..) in linux, and Hard Links and Unix Filesystem Nodes

EndAside

Share:
20,188

Related videos on Youtube

Ridza mnto
Author by

Ridza mnto

Updated on September 18, 2022

Comments

  • Ridza mnto
    Ridza mnto over 1 year

    Okay, first thing first, I'm new to Linux and I'm using Linux Mint.

    I learned that when I want to add more directories to my PATH (specifically my home directory) I need a Bash command that looks like PATH=$PATH:~, right?

    The question is why should I need to put $PATH there? It stands for system path, right? Will it work if I only type PATH=~? I mean I only want to add my home directory to the existing PATH directories.

    • Kusalananda
      Kusalananda over 5 years
      The important word in your question is "add". How would one usually add to a variable? Saying i=3 would not add to the original value of i. The same is true for strings when "add" means "append to".
  • ivanivan
    ivanivan over 5 years
    Additionally, instead of putting your entire home directory into your path, consider a ~/bin or ~/.bin and using that instead.
  • RalfFriedl
    RalfFriedl over 5 years
    The command . is a shell builtin equivalent to source. The meaning of . for the current directory comes from the file system, not from the shell.
  • nxnev
    nxnev over 5 years
    @Fólkvangr Even if it's safe to omit quotes in this case, please don't say that omitting them is "better" because, as Stéphane Chazelas said, "it can send a wrong message to beginners: that it may be all right not to quote variables. For instance, they may start thinking that if a=$b is OK, then export a=$b would be as well (which it's not in many shells as it's in arguments to the export command so in list context) or env a=$b".
  • flerb
    flerb over 5 years
    From the link: The basic rule of thumb is that you should double-quote every expansion. This prevents unwanted word splitting and globbing. When in doubt, quote it. It's easier to abide by the safe rule of thumb and learn about the safe POSIX-compliant exceptions later, which are listed on the link provided. Quotes are not necessary On the right hand side of a simple assignment but it will never hurt anything. I think my answer is long and meandering/potentially overwhelming enough so I just wanted to throw the quotes thing in as friendly advice to someone new to Linux.