4

In regular way to add a directory to PATH:

PATH=$PATH:/new-directory

Now the problem is if you add a new directory to the PATH then it will be added without checking if it's already in the PATH or not.

For example:

echo $PATH

gives:

/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

Now if I add /usr/bin:

PATH=$PATH:/usr/bin

Then PATH becomes:

/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/bin

So, if you can notice, now /usr/bin is repeated.

So, how can I add a new directory to the PATH without repeating?

3 Answers 3

7

A short way is to use:

[[ ":$PATH:" =~ ":/new-directory:" ]] || PATH="/new-directory:$PATH"

Explanations:

  • First command, the [[ conditional command, is for test.
  • The =~ binary operator return 0 if the string from the right which is considered an extended regular expression matches the string from the left, and 1 otherwise.
  • If the test is not passed (/new-directory was not found in PATH), thanks to the || logical OR control operator, the second command is executed: PATH="/new-directory:$PATH".

Observations:

  • You should always use quotes when you assign a string to a variable, even if the string is another variable: PATH="/new-directory:$PATH".
  • In general is better to add a new directory to the PATH environment variable in front to others directories, not after: PATH="/new-directory:$PATH". This because directories at the beginning of PATH take precedence over those that come later.
5

I use Stephen Collyer's bash_path_funcs, described in Linux Journal way back in 2000:

https://www.linuxjournal.com/article/3645 https://www.linuxjournal.com/article/3768 https://www.linuxjournal.com/article/3935

The addpath function adds an entry to a path only if it is not there in the first place. delpath -n deletes all non-existent directories from a path.

You can get the pathfunc.tgz file from https://web.archive.org/web/20061210054813/http://www.netspinner.co.uk:80/Downloads/pathfunc.tgz

7
  • I put the bash_path_funcs directory from this tarball under ~/.bash.d/ and chmod +x on all the scripts (except of course README) and then in my .bashrc I do for f in `find $HOME/.bash.d -type f -perm +111` ; do source "$f"; done
    – Jeff
    Feb 18, 2021 at 4:57
  • You are supposed to actually read the README file, and invoke the functions the way the README says.
    – waltinator
    Feb 19, 2021 at 1:22
  • I did, and I do. I was just adding the above comment to share a way to load the functions upon shell startup.
    – Jeff
    Feb 21, 2021 at 22:03
  • Thanks Jeff, that's a good addition. However, I needed to replace -perm +111 with -executable to just source all the executables. Now I can fill my bashrc with e.g. addpath $HOME/.yarn/bin without fear of duplication. Aug 10, 2021 at 7:43
  • 1
    do duplicates do anything bad? Sep 29, 2021 at 5:06
1

You can use this command:

if [[ ":$PATH:" != *":/new-directory:"* ]]; then PATH=${PATH}:/new-directory; fi

Now for the example above:

echo $PATH

gives:

/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

Now if I want to add /usr/bin:

if [[ ":$PATH:" != *":/usr/bin:"* ]]; then PATH=${PATH}:/usr/bin; fi

You can notice that PATH doesn't change:

/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

now to add other directory example /var/www

if [[ ":$PATH:" != *":/var/www:"* ]]; then PATH=${PATH}:/var/www; fi

Then output of echo $PATH gives:

/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/var/www

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .