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.
3

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.