Is there an Unix
convention for setting personal environment variables? I read they should be put in $HOME/.bash_profile
instead of $HOME/.bashrc
. Nonetheless, I was thinking of providing a way to distinguish my own variables. This way even though I would forget one I could tell at first glance whether it has been set by me or not. For instance when I do the autocompletion in the terminal I could make my variables start with an underscore, or a minus 'm' as in one of C++
language's conventions. I understand there might not be an absolute answer but I'd like to hear about some good practice and conventions that work toward this purpose: providing a simple way to distinguish system environment variables from personal ones.

- 866
2 Answers
Where to set environment variables is covered in What's the best distro/shell-agnostic way to set environment variables?
Regarding naming, the main reason to set environment variables is because an application uses them, so you don't get to choose the name.
There is no concept of namespaces for environment variables. The closest thing is to pick a prefix, generally of the form SOMETHING_
(i.e. the prefix ends with an underscore and you have variables SOMETHING_FOO
, SOMETHING_BAR
, …). But most variables aren't for a specific application, but rather a family of applications. If a variable is only meaningful in one application, it should generally be a command line option. So there isn't much need for namespaces.
If you're defining variables only for use on the command line, then don't use environment variables, use shell variables. (See Difference between environment variables and exported environment variables in bash) If you define a variable in a shell script and you don't use export
, that's a shell variable, not an environment variable, and it's only visible in the shell where you defined them. So if you're defining a variable for use on the command line:
- Define it in your shell interactive startup file (
~/.bashrc
for bash,~/.zshrc
for zsh,~/.config/fish/config.fish
for fish). - Don't
export
it. - There's a widespread convention that environment variables are all-uppercase and shell variables are all-lowercase.
For your own use, pick whatever names you like, as long as they don't conflict with environment variables that you use (environment variables are automatically imported as shell variables). I don't recommend an initial underscore because that's what bash and zsh's completion systems use internally.

- 829,060
Here are my recommendations for where to set the environment, along with explanations.
The relevant details are:
The user profile file is
~/.bash_profile
,~/.bash_login
, or~/.profile
. I suggest using one of the first two, because the last one overlaps with other shells. However, see Note on GUI login at the end.The user rc file is
~/.bashrc
.An interactive login shell (e.g. a console login, or
ssh
login) reads the profile file only.A noninteractive login shell is rare, but it might occur run during GUI login. Either way, if this is a Bash shell, it acts as a noninteractive login shell, and reads the profile file only.
An interactive nonlogin shell (e.g. new tab in XTerm/Konsole) reads the rc file.
A noninteractive nonlogin shell (e.g. shell script) reads neither, with one important exception: If started by
ssh
, it reads the rc file.
The exception involving ssh
is motivated by the fact that when a script is run through ssh (ssh $host my_remote_script
), the environment (mainly PATH
) is not already set up, as is the case when running a local script. Thus, IMO, the exception is a motivation to set the environment in ~/.bashrc
, so that the same environment is used for both locally-invoked and remotely-invoked scripts.
Based on all this, my recommendations are:
Profile file:
- Do not set anything that might be useful to a remotely-invoked script, including
PATH
. - Source the rc file unconditionally:
. ~/.bashrc
.
- Do not set anything that might be useful to a remotely-invoked script, including
Rc file:
- Set environment variables as needed.
Beware that the file will be sourced when the environment is already set (by interactive nonlogin shells). So, if you unconditionally do
PATH=$HOME/bin:$PATH
, you might end up withPATH=$HOME/bin:$HOME/bin:...
after sourcing it twice (an annoyance, not an error). An easy fix is to guard the environment setting:# ~/.bashrc if [ ! "${MY_ENV_SET:-}" ]; then PATH=... ... export MY_ENV_SET=1 fi
Only define shell niceties for interactive shells:
... [ "$PS1" ] || return 0 PS1=<fancy_colored_prompt> source ~/.bash_alias eval $(dircolors -b ~/.dircolors) source /etc/bash_completion
GUI login. One last important thing you need to consider is how your GUI sets PATH
during startup. This might be done using Bash, or not. In my case, I use KDE, and this file is sourced during startup:
# ~/.kde/env/path.sh
# https://userbase.kde.org/Session_Environment_Variables
PATH=$(env -i /bin/bash -lc 'echo $PATH')
This invokes a (rare) noninteractive login Bash shell, using an empty environment, which also sources the rc file, and all is consistent.
If you are using another GUI (Gnome?), you should look into how PATH
is set during its startup. If your GUI sources ~/.profile
, make sure to source the rc file from there as well.

- 579
-
Your facts are mostly correct but your advice is almost consistently bad. See http://unix.stackexchange.com/q/88201 and http://unix.stackexchange.com/a/3085 .
~/.bash_profile
is not read by most GUI logins whereas~/.profile
is, so.profile
is preferable.~/.bashrc
is only read by interactive shell so it should never set environment variables, otherwise they are not set by programs that aren't started from a terminal. The profile file should not source.bashrc
unconditionally, only if the shell is interactive. – Gilles 'SO- stop being evil' Aug 13 '16 at 23:01 -
In any case this, you aren't answering the question, which is not where to set environment variables but how to name them. – Gilles 'SO- stop being evil' Aug 13 '16 at 23:02
-
-
Other than that, instead of distastefully dismissing advice (by shamefully calling it "consistently bad") and appealing to the logical fallacy that is an argument of authority, I challenge you to take time and explain what you find "consistently bad", or else retract such comments. Thanks! – Matei David Aug 14 '16 at 00:29
-
To address your remaining argument, apart from the GUI startup issue- Any program not started from the terminal will (a) have the environment already set by the GUI, and (b) if for some peculiar reason they don't, and they need to source
~/.profile
, sourcing the rc from there covers that case. In your last sentence, "should not" is probably a personal preference. I am not saying your scheme doesn't work, I am only challenging your assertion that mine is "consistently bad" or even just "bad". IMO, these are different ways of setting things up. – Matei David Aug 14 '16 at 00:55
$HOME/.bash_profile
, and they are yours since are put in your profile..bash_profile
is executed for login shells, while.bashrc
is executed for interactive non-login shells. – Aug 12 '16 at 14:55