171

Problem

I have an Ubuntu 11.04 Virtual Machine and I wanted to set up my Java development environment. I did as follows

  1. sudo apt-get install openjdk-6-jdk
  2. Added the following entries to ~/.bash_profile

    export JAVA_HOME=/usr/lib/jvm/java-6-openjdk
    
    export PATH=$PATH:$JAVA_HOME/bin
    
  3. Save the changes and exit

  4. Open up a terminal again and typed the following

    echo $JAVA_HOME   (blank)
    echo $PATH        (displayed, but not the JAVA_HOME value)
    
  5. 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

  1. 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.
  2. Was in this case my terminal a non-login shell?
  3. 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?
216

~/.bash_profile is only sourced by bash when started in interactive login mode. That is typically only when you login at the console (Ctrl+Alt+F1..F6), or connecting via ssh.

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 change PATH)

  • 5
    I've found that when opening a Terminal from the sidebar in Ubuntu 12 the ~/.profile file is not loaded. – jcollum Mar 24 '13 at 17:20
  • 3
    @jcollum That's good. .profile should only be sourced when you log in. – geirha Mar 30 '13 at 6:59
  • 2
    oh, opening a terminal is not the same as logging in... I was thinking logging in to the terminal. – jcollum Mar 31 '13 at 16:53
  • 2
    Bear in mind that .profile is ignored by bash if .bash_profile exists. See my answer here and man bash for more details. – terdon Mar 11 '14 at 0:58
  • 3
    @terdon, yes, but bash is not involved when logging in graphically, so it goes straight for .profile. – geirha Mar 11 '14 at 8:44
45

You can check if your Bash shell is started as a login-shell by running:

shopt login_shell

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:

When bash is invoked as an interactive login shell, or as a non-interactive shell with the --login option, it first reads and executes commands from the file /etc/profile, if that file exists. After reading that file, it looks for ~/.bash_profile, ~/.bash_login, and ~/.profile, in that order, and reads and executes commands from the first one that exists and is readable.

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.

  • 7
    Thanks a lot for the shotp login_shell command. Awesome!! – Viriato Apr 11 '12 at 18:26
26

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

  • 1
    What are the downsides to enabling this setting? – chrish Nov 15 '17 at 14:30
  • 1
    @chris you are just loading code a little more code than necessary in a lot of occasion. It probably doesn't matter if your ~/.bash_profile is evaluating really quickly, which is probably the case. A good thing to check is to chase out any calls to other processes that are usually quite costly. – vaab Mar 8 '18 at 4:08
14

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 run su 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.

  • 1
    That is what I had done and it worked, but check what the guy in the bottom says, he suggests is a bad idea to put it in bashrc and put it on the profile instead. ....Hey both ways work, thanks a lot. – Viriato Apr 11 '12 at 18:25
2

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:

  • all processes on linux have and uses environment variables
  • environment variables are inherited
  • thus setting them once on the father of all your process is enough (especially if it requires some computation time.)
  • the father of all your process is typically launched after you log in on your device (give your credentials).
  • there are things you might want to do only once when you log in on your computer (check for new mail for instance...).

So "login" time is typically:

  • In console mode, when you login (with Ctrl-Alt F1) or through ssh, as the shell will be the father of all process, it'll load your ~/.bash_profile.
  • In graphic mode, when you open your session, the first process (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:

  • you use bash shell,
  • you have a ~/.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:

    • make a new shell window/pane in graphical sessions.
    • calling bash
    • screen new pane or tab. (not tmux !)
    • any bash instance in a graphical console client (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:

    • console login (Ctrl-Alt F1),
    • ssh logins to this machine,
    • tmux new pane or windows (default settings), (not screen !)
    • explicit calls of bash -l,
    • any bash instance in a graphical console client (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.

  • On the occasions that bash does load a profile file, it will load .profile if .bash_profile does not exist. – muru Mar 8 '18 at 4:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.