Problem
I have an Ubuntu 11.04 Virtual Machine and I wanted to set up my Java development environment. I did as follows
sudo apt-get install openjdk-6-jdk
Added the following entries to ~/.bash_profile
export JAVA_HOME=/usr/lib/jvm/java-6-openjdk export PATH=$PATH:$JAVA_HOME/bin
Save the changes and exit
Open up a terminal again and typed the following
echo $JAVA_HOME (blank) echo $PATH (displayed, but not the JAVA_HOME value)
Nothing happened, like if the export of JAVA_HOME and it's addition to the PATH were never done.
Solution
I had to go to ~/.bashrc and add the following entry towards the end of file
#Source bash_profile to set JAVA_HOME and add it to the PATH because for some reason is not being picked up
. ~/.bash_profile
Questions
- Why did I have to do that? I thought bash_profile, bash_login or profile in absence of those two get executed first before bashrc.
- Was in this case my terminal a non-login shell?
- If so, why when doing su after the terminal and putting the password it did not execute profile where I had also set the exports mentioned above?
~/.bash_profile
is only sourced by bash when started in login mode. That is typically when you log in at the console (Ctrl+Alt+F1..F6), connect via ssh, or usesudo -i
orsu -
to run commands as another user.When you log in graphically,
~/.profile
will be specifically sourced by the script that launches gnome-session (or whichever desktop environment you're using). So~/.bash_profile
is not sourced at all when you log in graphically.When you open a terminal, the terminal starts bash in (non-login) interactive mode, which means it will source
~/.bashrc
.The right place for you to put these environment variables is in
~/.profile
, and the effect should be apparent next time you log in.Sourcing
~/.bash_profile
from~/.bashrc
is the wrong solution. It's supposed to be the other way around;~/.bash_profile
should source~/.bashrc
.See DotFiles for a more thorough explanation, including some history of why it is like it is.
(On a side note, when installing openjdk via apt, symlinks should be set up by the package, so that you don't really need to set
JAVA_HOME
or changePATH
)You can check if your Bash shell is started as a login-shell by running:
If the reply is
off
you are not running a login shell.Read the Bash manual's invocation section on how Bash reads (or does not read) different configuration files.
Excerpt from
man bash
:su
on the other hand also does not start a login shell by default, you have to tell it to do so by using the--login
option.I think it is worth mentioning that you can change the default of gnome-terminal to use a login shell (ie. bash -l) by editing the profile preferences.
go to Edit -> Profile Preferences -> Title and Command tab check the "Run command as a login shell" option
If you open a terminal or run
su
the shell is not executed as a login shell but as a normal interactive shell. So it reads~/.bashrc
but not~/.bash_profile
. You can runsu
with the-l
option to make it run your shell as a login shell.When you are working with a GUI the shell is usually never run as a login shell so it's usually fine to put all yout stuff in
~/.bashrc
.TL;DR
In classical recommended ubuntu setup,
~/.bash_profile
gets evaluated only in specific occasions. And it makes sense.Put your stuff in
~/.bashrc
, it'll get evaluated everytime.Ok, I want to understand, why does this make sense ?
Keypoints to understand what is going on:
So "login" time is typically:
ssh
, as the shell will be the father of all process, it'll load your~/.bash_profile
.gnome-session
for classical ubuntu) will be in charge to read.profile
.Ok, so where to put my stuff ?
It's rather complex, the full story is here. But here is a run down that is pretty common for ubuntu users. So considering that:
bash
shell,~/.bash_profile
and follow the recommendation to add the loading of~/.bashrc
in your~/.bash_profile
so as to get at least one file that gets evaluated whatever is the invocation mecanism.This is a quick suggestion of where to put things.
~/.bashrc (Gets evaluated in all occasion, provided you follow the recommendation)
For fast-evaluation environment variable and code for your user-only and bash-only command-line usage (aliases for instance). bashism are welcome.
It gets loaded on itself upon:
bash
screen
new pane or tab. (nottmux
!)terminator
/gnome-terminal
...) if you don't tick option "run command as login shell".And it will get loaded in all the other occasion thanks to the prior recommendation.
~/.bash_profile (Gets evaluated in specific occasion only)
For slow-evaluation environment variable and code for your user-only and console-session processes. bashism are welcome. It gets loaded on:
tmux
new pane or windows (default settings), (notscreen
!)bash -l
,terminator
/gnome-terminal
...) only if you tick option "run command as login shell".~/.profile (Gets evaluated only in graphical-session)
For slow-evaluation environment variables and with no-bashism for your user-only and all graphical-session processes. It gets loaded upon login in your graphical UI.
When you do
sudo su
the shell is not executed, instead of that try withsudo su -
this will load~/.bash_profile
as source by default.They want you to put it in ~/.bash_aliases now
in ~/.bashrc there is this code pointing it out: