13

I recently started configuring a OSX 10.7 environment for development. I've installed HomeBrew, and added the following to my .bash_profile:

export PATH="/usr/local/bin:/usr/local/sbin:~/bin:$PATH"        

Everything is working great except when I echo $PATH I get the following string of duplicates: /usr/local/bin:/usr/local/sbin:~/bin:/usr/local/bin:/usr/local/sbin:~/bin:/usr/local/git/bin:usr/local/bin:/usr/local/git/bin:usr/local/bin:/usr/local/git/bin:usr/local/bin:/usr/local/git/bin:usr/local/bin:/usr/local/git/bin:usr/local/bin:/usr/local/git/bin:usr/local/bin:/usr/local/git/bin:usr/local/bin:/usr/local/git/bin:/usr/local/git/bin:/usr/local/git/bin:/usr/local/git/bin:/usr/local/git/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/X11/bin

To make it more readable, these are all the paths:

/usr/local/bin
/usr/local/sbin
~/bin:/usr/local/bin
/usr/local/sbin
~/bin
/usr/local/git/bin
usr/local/bin
/usr/local/git/bin
usr/local/bin
/usr/local/git/bin
usr/local/bin
/usr/local/git/bin
usr/local/bin
/usr/local/git/bin
usr/local/bin
/usr/local/git/bin
usr/local/bin
/usr/local/git/bin
usr/local/bin
/usr/local/git/bin
/usr/local/git/bin
/usr/local/git/bin
/usr/local/git/bin
/usr/local/git/bin
/usr/bin
/bin
/usr/sbin
/sbin
/usr/local/bin
/usr/X11/bin

I don't think I've made any changes to path besides the single line in my .bash_profile. What is the best way for me to pair down those duplicates? Is there a way to hunt down which files are modifying my path and try to eliminate them?

4
  • Anything in /etc/paths.d/? Any other bash configuration files?
    – slhck
    Jul 16, 2012 at 17:53
  • 1
    I really wouldn't worry about it. Bash will only do a single lookup for a command name once during a session; afterwards, it stores the command's full path in an internal hash table. You will probably spend far more time looking for the source of the duplicates than bash will ever, cumulatively, spend searching for the location of executables in PATH directories.
    – chepner
    Jul 16, 2012 at 18:06
  • @slhck /etc/paths.d has one file with the line /usr/X11/bin in it. I haven't made any other bash configuration files that I know of (I only have .bash_profile in ~) Jul 16, 2012 at 18:20
  • See: superuser.com/questions/1216649/…, where a (partial) list of places to look for duplicates is given.
    – PatrickT
    May 21, 2020 at 16:24

4 Answers 4

8

Having made my comment, here are some suggestions for pruning $PATH anyway.

Looking at your path, it appears that .bash_profile is being executed twice, or the modification made in .bash_profile is duplicated elsewhere.

There are 7 duplicate additions of '/usr/local/git/bin' and 'use/local/bin' [sic], followed by 5 more copies of '/usr/local/git/bin'. Depending on how git is installed, you may be able to query your package manager about what files were installed with git; there could be some configuration files or modified system files that affect PATH.

Put set -x at the very top of your .bash_login, then start a new login shell. You should get a lot of output that shows exactly what bash is doing on startup, which should help you figure out where PATH is being modified. You can remove set -x once you figure it out or give up. If you don't find anything, you could also add it to the beginning of /etc/profile to trace what the system does before your own .bash_profile is processed.

3
  • I used set -x, saw that the only major modification to PATH was in my .bash_profile and removed that line. Now my path is much cleaner (don't know how that line managed to wreak so much havoc). Thanks so much for the answer @chepner! Jul 18, 2012 at 19:08
  • Can I configure the output of set -x to a log file?
    – baggiponte
    Nov 11, 2023 at 13:47
  • bash will write to whatever file descriptor is found in BASH_XTRACEFD, if defined. Something like exec {BASH_XTRACEFD}> log.txt will redirect the trace output to log.txt (using the redirection operator that automatically allocates a file descriptor and assigns it to a given name).
    – chepner
    Nov 13, 2023 at 14:20
9

I ran Ryan Thompson's script from the command line.
It removed all the duplicates for me, without changing the order, and without leaving a trailing :

PATH="$(perl -e 'print join(":", grep { not $seen{$_}++ } split(/:/, $ENV{PATH}))')"

In addition to the convenient 1-liner above, Ryan shares the (more structured) script he uses in his config to de-duplicate other variables and the PATH.

(See his Unix & Linux post for more details)

1
  • I can't get this fix to persist. It does clean duplicates from $PATH, but if I open a new Ubuntu WSL2 command prompt window, my $PATH is back to having duplicates. How can I make this permanent? Dec 24, 2020 at 15:40
3

I added this to my $HOME/.bashrc (you should also be able to add it to .bash_profile instead if you wish) to remove duplicate entries from the $PATH. I've only tested on linux but should also work on mac. It should be added after the initial export PATH.

export PATH=$(echo $PATH | awk -F: '
{ for (i = 1; i <= NF; i++) arr[$i]; }
END { for (i in arr) printf "%s:" , i; printf "\n"; } ')
1
  • 2
    This changes the order of entries in PATH. Dangerous!! May 28, 2017 at 21:41
0

An installation of git modified your .bash_profile without serious preliminary check. This installer corrupted it (apparently 12 times). Use the receipe suggested by rash, but just once to define the correct minimal PATH to include back in your .bash_profile.

You don't need to initialize your PATH in your .bashrc. This initialisation script is reserved to configuration which have to change with each level of shell, for example a prompt, a position, a color, but not a PATH.

You must log in to answer this question.

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