I modify my .bashrc frequently and then source it. However, when I have things like export PATH="~/bin:~/perl5/bin:$PATH" in my file, then the PATH environment variable grows every time I source the file.

For example, the first time .bashrc is sourced, the PATH variable consists of ~/bin:~/perl5/bin:/usr/bin:/bin.

The second time it consists of ~/bin:~/perl5/bin:~/bin:~/perl5/bin:/usr/bin:/bin.

The third time it consists of ~/bin:~/perl5/bin:~/bin:~/perl5/bin:~/bin:~/perl5/bin:/usr/bin:/bin.

Is there a simple way to make it only add anything that isn't already in the PATH?

link|improve this question
feedback

4 Answers

up vote 4 down vote accepted

Use the pathmunge() function available in most distro's /etc/profile:

pathmunge () {
if ! echo $PATH | /bin/egrep -q "(^|:)$1($|:)" ; then
   if [ "$2" = "after" ] ; then
      PATH=$PATH:$1
   else
      PATH=$1:$PATH
   fi
fi
}

edit: For zsh users, typeset -U <variable_name> will deduplicate path entries.

link|improve this answer
Thanks! It's not in /etc/profile on Debian Lenny, so I include it in my .bashrc. – molecules Oct 19 '10 at 16:15
Usage: pathmunge /some/path will place /some/path at the beginning of $PATH and pathmunge /some/path after will place /some/path at the end of $PATH – molecules Oct 19 '10 at 16:18
Cleaner way of doing the check to see if the hew directory exists in the current path, in modern bash shells: if ! [[ $PATH =~ (^|:)$1($|:) ]] ; then. – Christopher Cashell Oct 28 '10 at 16:38
feedback

Set your path explicitly.

link|improve this answer
Thanks. I tried setting the path explicitly, but I have a .bashrc file that I use in multiple environments, so the exact default PATH is not always the same. – molecules Oct 19 '10 at 16:26
feedback

Only one string:

for i in $(echo $PATH|tr ":" "\n"|sort|uniq);do PATH_NEW="${PATH_NEW}$i:";done;PATH="${PATH_NEW%:}"
link|improve this answer
Thanks. One difficultly this would cause me is that it alphabetically (or ASCIIbetically) reorders the contents of $PATH. I like to put specific directories at the beginning of $PATH (like /home/username) so that my personal copies of executables are run instead of the built-in defaults. – molecules Oct 19 '10 at 16:32
feedback

I can think of two different ways you could resolve this. The first one, is to start your .bashrc with a line that explicitly sets your base PATH, that way every time you source it, it is reset to the base prior to adding additional directories.

For example, add:

# Reset the PATH to prevent duplication and to make sure that we include
# everything we want.
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

Alternately, you can check for an item before you add it to the path. To do that, you'd use something like:

if [[ $PATH =~ '~/perl5/bin' ]]
then
    PATH='~/perl5/bin:$PATH'
fi

The latter tends to get a little repetitive if you're adding a lot of entries, however, so I tend to stick with the former. If you wanted to use this and planned on adding a lot of entries, writing a bash function to handle it would be wise.

Note: The second option may only work as written in modern versions bash. The regular expression support is not a Bourne Shell (/bin/sh) feature, and may not exist in other shells. Also, the use of quotes may not be needed or may even cause problems on some newest versions of bash.

link|improve this answer
Thanks. I tried setting the path explicitly, but I have a .bashrc file that I use in multiple environments, so the exact default PATH is not always the same. – molecules Oct 19 '10 at 16:20
You can still handle that by checking in the script to see what your local hostname is, and then setting your absolute path appropriately for that server. – Christopher Cashell Oct 19 '10 at 16:26
True. I might eventually do that. Thanks! – molecules Oct 19 '10 at 16:35
feedback

Your Answer

 
or
required, but never shown

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