- Complete view of where the PATH variable is set in bash
- 5 Answers 5
- How do I find where the environment variables are defined in Linux
- 1 Answer 1
- Example
- How it works
- Other method
- How can I find out where an environment variable (like PATH) was set?
- 4 Answers 4
- How to determine where an environment variable came from?
- 8 Answers 8
Complete view of where the PATH variable is set in bash
I’ve read in a couple of places that the PATH is set in /etc/profile or the .profile file that’s in the home dir. Are these the only places that the path is set in? I want a better understanding of it. In the /etc/profile file, as the following comment says «system-wide .profile file for the Bourne shell» . Does that mean that profile files are the main configuration files for bash? In that file I don’t see the PATH var being set at all. In the .profile file in the home directory there’s this line:
That’s resetting PATH by the looks because it’s concatenating the already set $PATH string with $HOME/bin: right? But if etc/profile and ~/.profile are the only files setting PATH where is $PATH coming from in that line of code if it’s not defined in /etc/profile ? Can someone experienced please give a broad and detailed explanation of the PATH variable? Thanks!
5 Answers 5
There are many places where PATH can be set.
The login program sets it to a default value. How this default value is configured is system-dependent. On most non-embedded Linux systems, it’s taken from /etc/login.defs , with different values for root and for other users. Consult the login(1) manual on your system to find out what it does.
On systems using PAM, specifically the pam_env module, environment variables can be set in the system-wide file /etc/environment and the per-user file ~/.pam_environment .
Then most ways to log in (but not cron jobs) execute a login shell which reads system-wide and per-user configuration files. These files can modify the value of PATH , typically to add entries but sometimes in other ways. Which files are read depend on what the login shell is. Bourne/POSIX-style shells read /etc/profile and ~/.profile . Bash reads /etc/profile , but for the per-user file it only reads the first existing file among ~/.bash_profile , ~/.bash_login and ~/.profile . Zsh reads /etc/zshenv , ~/.zshenv , /etc/zprofile , ~/.zprofile , /etc/zlogin and ~/.zlogin . Many GUI sessions arrange to load /etc/profile and ~/.profile , but this depends on the display manager, on the desktop environment or other session startup script, and how each distribution has set these up.
The initial PATH variable is usually set in /etc/profile Sometimes a sys admin will also put PATH variables to source in /etc/profile.d
These are the system PATH vars that everyone who logs in inherits by default (unless over-ridden locally). This usually sets obvious paths, like /usr/bin , although at my job we use /opt and a few custom locations extensively, so those are set there as well.
On a per-user login basis accounts, PATH may also be defined in ~/.profile . That might define things that not all users have access to; maybe department heads can run binaries from /opt but other users aren’t bothered with those binaries. Users can modify that file themselves, too, and the nice thing about .profile is that it is not shell-specific; if you login, the PATH set there gets sourced.
For shell-specific logins, PATH may be defined in ~/.bash_profile , ~/.bashrc , or .cshrc , or similar. Users can set PATH here if they want specific paths for specific shells, or if they just happen to maintain all their personal preferences there.
In summary: /etc/profile and /etc/profile.d are traditionally cascading settings; they get inherited and usually are added to in personal dot-files (although a user could choose to override them instead). Personal dot-files are usually set by a user.
Of course, a shell has environment variables, too, so a local environment variable can also add or override default PATH in any of the configuration files.
How do I find where the environment variables are defined in Linux
I just started learning hadoop (CentOS7), here is a question about environment variable: In my VM, rxie is the logged on user: HADOOP_CONF_DIR = /opt/hadoop/hadoop-2.7.2/etc/rxie There is no path of /opt/hadoop/hadoop-2.7.2/etc/rxie it should be /opt/hadoop/hadoop-2.7.2/etc/hadoop I am trying to find out where the variable is defined so that I can correct it. here is what I come up:
bash-4.2# grep -r HADOOP_CONF_DIR ~/.* /root/./.bashrc:export HADOOP_CONF_DIR=$HADOOP_HOME/etc/hadoop
Please note HADOOP_CONF_DIR=$HADOOP_HOME/etc/hadoop is correct. I don’t see where the erroneous HADOOP_CONF_DIR is defined? It would be appreciated if anyone can enlighten me and offer a fix, thank you very much.
1 Answer 1
PS4='+ $BASH_SOURCE:$LINENO:' BASH_XTRACEFD=7 bash -xlic "" 7>trace.out
grep HADOOP_CONF_DIR trace.out
The output will show you every time that HADOOP_CONF_DIR was set, the file that set it, and the line number in that file.
Example
Let’s take as an example something that I have in my .bashrc file:
$ grep HISTFILESIZE trace.out ++ /home/john1024/.bashrc:193:export HISTFILESIZE=20000
This shows that is was line 193 of ~/.bashrc that set HISTFILESIZE .
How it works
This command starts a bash login shell with diagnostics turned on. The PS4 variable sets the prefix for the diagnostic output so that it contains the file name and line number. For more details, see here.
Other method
Although it is less reliable, one can also try:
grep HADOOP_CONF_DIR ~/.bashrc ~/.bash_profile ~/.profile /etc/profile.d/* /etc/profile /etc/bashrc
How can I find out where an environment variable (like PATH) was set?
I have a xterm with the bash shell in linux. When I echo $PATH , it is showing a directory and I want to know who put this directory in the PATH . How can I find out? Thanks!
4 Answers 4
Assuming your login shell is bash, you could start looking in the following files: /etc/profile , ~/.bashrc and ~/.bash_profile . If you invoke bash from another shell, then you might need to check what variables the other shell sets.
You probably cannot discover who, but you can find out which file is setting that. Look a the Bash documentation for the startup files. There are several that bash processes on startup to set $PATH and the other environment variables.
Also you could take a look to the file /etc/environment
This answer assumes your login shell is bash.
I use an alias that simulates the opening of a login shell and outputs verbose logs to stdout.
Depending on how you configure your dotfiles, you might want to choose something other than ~/.bashrc , however, for my purposes, this works because ~/.bashrc is where I source all of my various configuration files and exports.
alias simlogin='PS4='\''+~/.bashrc> '\'' BASH_XTRACEFD=7 bash -xl 7>&2'
Note that after you run this command, your current shell will output a trace on every subsequent prompt and command, so you’ll probably want to exit the shell after you find what you need.
There’s a good answer here that can help you improve this debugging experience by redirecting the debug log output to a file (or other location).
How to determine where an environment variable came from?
I feel like I must be forgetting to look in some place obvious. Is there a trick for figuring this out?
And /etc/env.d/* files. But doing grep -R «YOUR_VARIABLE» /etc/ is probably the best way to find out.
@rozcietrzewiacz the simplest way. if variable is indeed located somewhere under /etc/ (like in my case); if you post it as answer, I would upvote 😉
In macos, /etc/env* do not exist. The answer in the macos comment also does not work. I will add macos as an additional tag to this question
8 Answers 8
If zsh is your login shell:
PS4='+$BASH_SOURCE> ' BASH_XTRACEFD=7 bash -xl 7>&2
That will simulate a login shell and show everything that is done (except in areas where stderr is redirected with zsh ) along with the name of the file currently being interpreted.
So all you need to do is look for the name of your environment variable in that output. (you can use the script command to help you store the whole shell session output, or for the bash approach, use 7> file.log instead of 7>&2 to store the xtrace output to file.log instead of on the terminal).
If your variable is not in there, then probably the shell inherited it on startup, so it was set before like in PAM configuration, in ~/.ssh/environment , or things read upon your X11 session startup ( ~/.xinitrc , ~/.xsession ) or set upon the service definition that started your login manager or even earlier in some boot script. Then a find /etc -type f -exec grep -Fw THE_VAR <> + may help.