278

I have a Linux instance that I set up some time ago. When I fire it up and log in as root there are some environment variables that I set up but I can't remember or find where they came from.

  • I've checked ~/.bash_profile, /etc/.bash_rc, and all the startup scripts.
  • I've run find and grep to no avail.

I feel like I must be forgetting to look in some place obvious. Is there a trick for figuring this out?

peterh
  • 9,488
  • 16
  • 59
  • 88
Joel
  • 2,883
  • 3
  • 16
  • 5
  • 14
    `/etc/environment` is another one. – derobert Aug 20 '10 at 18:44
  • 12
    And `/etc/env.d/*` files. But doing `grep -R "YOUR_VARIABLE" /etc/` is probably the best way to find out. – rozcietrzewiacz Aug 28 '11 at 00:53
  • 2
    On Mac OS X, see also [How do I find where an environmental variable got set?](http://apple.stackexchange.com/questions/51735/how-do-i-find-where-an-environmental-variable-got-set) – Gilles 'SO- stop being evil' May 21 '12 at 21:06
  • @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 ;) – Line Sep 02 '19 at 09:34
  • 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 – R71 Jun 03 '23 at 13:56

8 Answers8

265

If zsh is your login shell:

zsh -xl

With bash:

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.

Stéphane Chazelas
  • 522,931
  • 91
  • 1,010
  • 1,501
  • 8
    Impressive and helpful, thank you. For us n00bs, would you explain a bit more about the mode and how do we get out of the mode this puts us in? For example, we cannot simply pipe grep this output. – Geoffrey Hale Feb 10 '17 at 18:13
  • 14
    @GeoffreyHale if you `zsh -xl 2>&1` , i.e. merge the stderr and stdout ouputs, you can grep as usual. – Rakesh Aug 07 '17 at 20:04
  • 2
    Is there any way to do this with the `fish` shell? – Nick Sweeting May 07 '18 at 16:42
  • Even if I use `zsh -xl 2>&1`, somehow I can't grep normally. Apparently the output does not contain proper newlines or something. – xeruf Jul 23 '19 at 09:25
  • 1
    I think you could just use `PS4='+$BASH_SOURCE> ' BASH_XTRACEFD=7 bash -xl 7>/tmp/$(uuidgen)`, then grep on that random file as well. – bjd2385 Sep 08 '19 at 14:42
  • 3
    Fantastic masterly possession of bash – Alexander.Iljushkin Nov 11 '19 at 19:58
  • wow, I'm impressed. – Andrew Nov 27 '19 at 21:31
  • Comparing *bash* environment when running with `BASH_XTRACEFD`... I find the lack of resemblance between *$PATH*s disturbing [*ventilator breaths*]. – Rian Rizvi Apr 14 '20 at 19:17
  • This should definitely be the right answer – ErniBrown Sep 29 '20 at 06:58
  • Of course. This is so obvious, esp the '7'. :-) – Tom Russell Aug 15 '21 at 23:31
  • Is there a way to get this to work on Mac OSx? I've tried to write the out to `file.log` as you suggested, but it doesn't look like BASH_XTRACEFD is available to me. – A.Ellett Apr 29 '22 at 22:32
  • very interesting ! is there an equivalent for tsch instead of bash ? – servoz Nov 18 '22 at 11:18
  • Do you know how are some environment variables such as `DISPLAY` set? Because I used `grep` to find this variable but I did not found any file which sets this variable. And this one is actually set because if I type in a shell `echo $DISPLAY` I can get: `:0` but I don't understand how `DISPLAY` obtains that value – Edgar Magallon Dec 30 '22 at 21:53
115

Some places to look first:

System wide

  • /etc/environment: specifically meant for environment variables
  • /etc/env.d/*: environment variables, split in multiple files
  • /etc/profile: all types of initialization scripts
  • /etc/profile.d/*: initialization scripts
  • /etc/bashrc, /etc/bash.bashrc: meant for functions and aliases

User specific

  • ~/.profile: used for all shells
  • ~/.pam_environment: part of Pluggable Authentication Modules for Linux
  • ~/.bash_profile: initialization for login (bash-)shells
  • ~/.bashrc: initialization for all interactive (bash-)shells
  • ~/.cshrc, ~/.zshrc, ~/.tcshrc: similar for non-bash shells
beetstra
  • 1,251
  • 1
  • 8
  • 4
  • 1
    This is comprehensive! – jdhao Oct 15 '20 at 09:22
  • 6
    Also check `~/.pam_environment` if on Ubuntu as this is the [recommended location](https://help.ubuntu.com/community/EnvironmentVariables#A.2BAH4-.2F.pam_environment) for storing user environment variables. – David Nov 04 '20 at 15:33
  • `~/.pam_environment` was it, still set from back when I used Ubuntu, and now activated under Linux Mint – Josh Hansen Feb 28 '23 at 23:58
84

If you use the env command to display the variables, they should show up roughly in the order in which they were created. You can use this as a guide to if they were set by the system very early in the boot, or by a later .profile or other configuration file. In my experience, the set and export commands will sort their variables by alphabetical order, so that listing isn't as useful.

Anthon
  • 78,313
  • 42
  • 165
  • 222
Ben Combee
  • 2,449
  • 1
  • 17
  • 6
  • 2
    That's great... except I'm trying to find out what's *clearing* an environment variable (set in /etc/environment). :-) (And yes, it's being set initially... I'm adding lines in scripts in various to log where it gets cleared...) – Michael Scheper Jul 23 '15 at 02:12
  • 4
    this doesn't answer his question. he doesn't want to know the value of the enviornmental variable, he wants to know the location of the configuration file the shell is referencing to get that environmental variable. – Andrew Nov 27 '19 at 21:27
50

@Cian is correct. Other than using find and grep, there isn't much you can do to discover where it came from. Knowing that it is indeed an environment variable, I would attempt focusing your search in /etc/ and your home directory. Replace VARIABLE with the appropriate variable you're searching for:

$ grep -r VARIABLE /etc/*

$ grep -r VARIABLE ~/.*

Aaron Toponce
  • 4,514
  • 2
  • 18
  • 12
27

If you put set -x in your .profile or .bash_profile, all subsequent shell commands will be logged to standard error and you can see if one of them sets these variables. You can put set -x at the top of /etc/profile to trace it as well. The output can be very verbose, so you might want to redirect it to a file with something like exec 2>/tmp/profile.log.

If your system uses PAM, look for pam_env load requests in /etc/pam.conf or /etc/pam.d/*. This module loads environment variables from the specified files, or from a system default if no file is specified (/etc/environment and /etc/security/pam_env.conf on Debian and Ubuntu). Another file with environment variable definitions on Linux is /etc/login.defs (look for lines beginning with ENV_).

Gilles 'SO- stop being evil'
  • 807,993
  • 194
  • 1,674
  • 2,175
8

For zsh users, tracing the files that are accessed (during startup) can be useful, they are not too many and one can look through them one-by-one to find where something was defined.

zsh -o SOURCE_TRACE
Erik Živković
  • 181
  • 1
  • 3
5

Check your startup scripts for files that they source using . (dot) or source. Those files could be in other directories besides /etc and $HOME.

Dennis Williamson
  • 6,620
  • 1
  • 34
  • 38
-1

environment variables are stored in /etc/profile file so do more /etc/profile and just check for env variables you want and if /etc/profile is not present then lokk for .profile file in your home directory

  • 1
    Environment variables are **not** stored in `/etc/profile`, you can define them there system wide for e.g. `bash` when used as a login shell. They are stored by the shell process after reading in definitions from files and/or commandline. – Anthon Jan 07 '15 at 11:33