Where is my PATH variable being set?

8,048

Solution 1

The PATH could be set in any of the various files bash reads when it starts. To find them all, run this:

grep --color -H 'PATH=' ~/.bashrc ~/.profile ~/.bash_profile ~/bash.login \
                     ~/.bash_aliases /etc/bash.bashrc /etc/profile \
                     /etc/profile.d/* /etc/environment 2> /dev/null

Those are the standard ones. If you are also sourcing other files from one of those, things can get more complex.

Anyway, to fix it—assuming you haven't done anything to the global files in /etc/—you can run this:

sed -i '/PATH=/d' ~/.bashrc ~/.profile ~/.bash_profile ~/bash.login ~/.bash_aliases 

That will delete any lines setting PATH from those files. Now, add the right one in the right place:

pp='PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/home/jgrande/android-sdk-linux/platform-tools:/usr/lib/jvm/java-7-openjdk-amd64/bin/:/usr/lib/jvm/java-7-openjdk-amd64/jre/bin'
[[ -e '~/.bash_profile' ]] && echo "$pp" >> ~/bash_profile ||
                              echo "$pp" >> ~/.profile

When invoked as a login shell, bash reads .bash_profile if present and, if not, it reads ~/.profile (it will ignore .profile if .bash_login is present but I assume it isn't). So, the commands above will first save your desired path as $pp and then check whether a ~/.bash_profile exists, add the path definition to it if it does and, if it doesn't, it will add it to ~/.profile.

In the future, to avoid this kind of issue, use a function to add directories to your $PATH. Add these lines to your ~/.profile:

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

Then, to add something to the beginning of your $PATH, add this line to ~/.profile:

pathmunge "/path/to/foo"

And to add it to the end:

pathmunge "/path/to/foo" after

The function will only add a new directory to the $PATH if it isn't already there.

Solution 2

You have applied a hurricane of randomness to your configs!

If you cannot undo your edits to the files in /etc, you might have to reinstall bash!

You can adjust your personal PATH without changing any files in /etc. For example read these answers. I, of course, prefer my answer.

You could determine exactly where you are going astray by reading man bash, man less, and with one eye on the INVOCATION section of man bash, use less on the startup files. Whenever they seem to transfer control (source, .), use less's ! command to read that file. Use less's / command to search for the string PATH= to find PATH assignments in each file. Remember to be as dumb as bash.

You could compare (with diff) the startup files (.bashrc,.profile, .bash_login) between your $HOME and that of " another user".

Solution 3

To find all places where $PATH environment variable is changed use this:

sudo grep -rnw --exclude-dir={boot,dev,lib,media,mnt,proc,root,run,sys,/tmp,tmpfs,var} '/' -e "PATH="

This will search all directories on your system excluding virtual file system directories. In my case with three distros mounted, 697 files are returned.


A more targeted approach for OP is to search for specific path name. You could look for the program that is setting the unusual part of $PATH containing:

/usr/local/java/jdk1.7.0_79/bin

Run this in the terminal:

sudo grep -rnw --exclude-dir={boot,dev,lib,media,mnt,proc,root,run,sys,/tmp,tmpfs,var} '/' -e "/usr/local/java/jdk1.7.0_79/bin"

If the first directory in the $PATH is not the culprit then search for the last one:

/usr/lib/jvm/java-7-openjdk-amd64/jre/bin

grep will return the name of the script / file that is setting the $PATH.

Share:
8,048

Related videos on Youtube

user1617942
Author by

user1617942

Updated on September 18, 2022

Comments

  • user1617942
    user1617942 over 1 year

    I'm trying to set my path variable to look like this:

    /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/home/jgrande/android-sdk-linux/platform-tools:/usr/lib/jvm/java-7-openjdk-amd64/bin/:/usr/lib/jvm/java-7-openjdk-amd64/jre/bin
    

    And for some reasons, no matter what file I edit, the variable always ends up looking like this (with the java path repeating a bunch of times):

    PATH=/usr/local/java/jdk1.7.0_79/bin:/home/jgrande/bin:/usr/local/java/jdk1.7.0_79/bin:/home/jgrande/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/usr/local/java/jdk1.7.0_79/bin:/usr/local/java/jdk1.7.0_79/jre/bin:/usr/local/java/jdk1.7.0_79/bin:/usr/local/java/jdk1.7.0_79/jre/bin
    

    I've tried to edit my personal .bashrc and .profile as well as /etc/environment, /etc/bash.bashrc, /etc/profile, and set it in /etc/profile.d. Now, there is jdk.sh in /etc/profile.d where the PATH variable is identical to the incorrect one I posted above. However, I tried to comment out the line and even remove jdk.sh altogether and that still didn't fix it.

    Otherwise, I've noticed that if I log in as another user, I'll have the correct PATH variable, and don't have the messed up one with java being repeated a bunch of times.

    So, I was wondering, where else could my PATH variable be defined that I haven't checked yet?

  • Serhat Ozgel
    Serhat Ozgel over 5 years
    you are a life saver! Somebody changed the path in xinitrc of xfce4... I don't think I would have found that without your grep!
  • nishanthshanmugham
    nishanthshanmugham almost 3 years
    fwiw, my (unedited) /etc/profile on Fedora 34 has a pathmunge function that seems to have the same goal as the one you've shared. :)
  • terdon
    terdon almost 3 years
    @nishanthshanmugham yes, this function is included by default on Red Hat based systems. I originally took it from a Red Hat I was running circa 2004 or so.