Why doesn't my ~/.bash_profile work?

The file ~/.bash_profile is read by bash when it is a login shell. That's what you get when you log in in text mode.

When you log in under X, the startup scripts are executed by /bin/sh. On Ubuntu and Mint, /bin/sh is dash, not bash. Dash and bash both have the same core features, but dash sticks to these core features in order to be fast and small whereas bash adds a lot of features at the cost of requiring more resources. It is common to use dash for scripts that don't need the extra features and bash for interactive use (though zsh has a lot of nicer features).

Most combinations of display manager (the program where you type your user name and password) and desktop environment read ~/.profile from the login scripts in /etc/X11/Xsession, /usr/bin/lightdm-session, /etc/gdm/Xsession or whichever is applicable. So put your environment variable definitions in ~/.profile. Make sure to use only syntax that dash supports.

So what should you put where?

  • A good .bash_profile loads .profile, and loads .bashrc if the shell is interactive.

    . ~/.profile
    if [[ $- == *i* ]]; then . ~/.bashrc; fi
    
  • In .profile, put environment variable definitions, and other session settings such as ulimit.

  • In .bashrc, put bash interactive settings such as aliases, functions, completion, key bindings (that aren't in .inputrc), …

See also Difference between Login Shell and Non-Login Shell? and Alternative to .bashrc.


.bash_profile is the startup configuration script of bash. There exists no standard mandating X to source .bash_profile.

What you are thinking of is rather .profile. Originally it was the startup configuration file of the bourne shell (sh). Today many distributions have their desktop environment set up to source .profile. Note that this is also not a standard, but it seems to be a convention.

Debian used to source .profile at graphical login (wiki page as of 2013) now it doesn't (wiki page as of 2016).

Arch sources .xprofile at graphical login (wiki page as of 2013).

Ubuntu used to discourage using .profile (wiki page as of 2013) now it doesn't discourage anymore (wiki page as of 2016).


Regarding your other question: Why doesn't my ~/.bash_profile work? That is the expected behaviour.

The behaviour, in short, is as follows:

  • bash started as an interactive login shell: reads ~/.profile
  • bash started as an interactive non-login shell: reads ~/.bashrc

For more details see my answer to a similar question in askubuntu: https://askubuntu.com/questions/132276/configure-gnome-terminal-to-start-bash-as-a-login-shell-doesnt-read-bashrc/132319#132319


A couple of issues arise when trying to reload/source ~/.profile file. [This refers to Ubuntu linux - in some cases the details of the commands will be different]

  1. Are you running this directly in terminal or in a script?
  2. How do you run this in a script?

Ad. 1)

Running this directly in terminal means that there will be no subshell created. So you can use either two commands:

source ~/.bash_profile

or

. ~/.bash_profile

In both cases this will update the environment with the contents of .profile file.

Ad 2) You can start any bash script either by calling

sh myscript.sh 

or

. myscript.sh

In the first case this will create a subshell that will not affect the environment variables of your system and they will be visible only to the subshell process. After finishing the subshell command none of the exports etc. will be applied. THIS IS A COMMON MISTAKE AND CAUSES A LOT OF DEVELOPERS TO LOOSE A LOT OF TIME.

In order for your changes applied in your script to have effect for the global environment the script has to be run with

.myscript.sh

command.

In order to make sure that you script is not runned in a subshel you can use this function. (Again example is for Ubuntu shell)

#/bin/bash

preventSubshell(){
  if [[ $_ != $0 ]]
  then
    echo "Script is being sourced"
  else
    echo "Script is a subshell - please run the script by invoking . script.sh command";
    exit 1;
  fi
}

I hope this clears some of the common misunderstandings! :D Good Luck!