29

I'm trying to integrate RVM with gnome-terminal.

Per default, gnome-terminal does not start bash as a login shell. I enabled run command as a login shell as suggested in this answer about the same topic setting up RVM, but when I do this the .bashrc file is not read.

For example, I create an environment variable in .bashrc and then when I start a new gnome-terminal I cannot read it. I need to run explicitly source .bashrc to read the file.

Is this the expected behavior?

4 Answers 4

47

Yes, if gnome terminal is configured to start bash as login shell then bash will not read .bashrc

The behaviour, in short, is as follows:

  • bash started as an interactive login shell: it reads .profile but not .bashrc
  • bash started as an interactive non-login shell: it reads .bashrc but not .profile

(there are more peculiarities about this elaborated below)

There is certainly some rationale behind this design decision which made sense at some time in the past. But now it is just an annoying legacy which confuses newcomers.


Some explanation of the terminology:

  • An interactive shell is a shell with which you can interact. That means you can type commands in it.
  • A non-interactive shell is a shell with which you cannot interact. Shell scripts run in non-interactive shells.
  • A login shell is the shell which is started when you login to your system.
  • A non-login shell is a shell which is started after the login process.

Typically when you work in gnome-terminal you work with bash as a interactive non-login shell. Interactive because you type commands in it. Non-login because you did not login with the shell (gnome is the "login shell" in this case).

Apart from the configuration files loaded during startup there is not much difference between a login shell and a non-login shell.


More background:

There is some confusion in the internet about where to put configuration. Some say .bashrc but as you experienced .bashrc is not always loaded. Some say .profile which is a bit more correct. But it also has caveats. One is that .profile is typically only read by login shells. Another is that .profile is read by more programs than just bash. So one must take care to not put bash specific things in .profile.

Ideally we put in .bashrc only settings relating to the bash shell itself. And in .profile put environment variables not bash related. But this is often mixed up due to a variety or reasons. Some of them are:

  • bash settings typically work well if put in .profile. This is because .profile, if it is read, is typically read by bash.
  • environment variables that are not bash related work well in .bashrc. Because bash does not care about those but they are set so they work.
  • newcomers often can't tell which setting is bash related and which is not.

To add to this confusion gnome-terminal can be set to login shell which changes behaviour intransparently.

There are also some questionable "fixes" or workarounds to this problem. Debian (and ubuntu) for example has a default .profile set up to read .bashrc. In effect both .profile and .bashrc are read on login shells. But just .bashrc on non login shells. This in turn caused many to learn to put everything in .bashrc because it is always loaded.

I find this questionable because .profile is not a bash exklusive configuration file. It is global configuration file read by many programs. So it should not load .bashrc. (i know it loads .bashrc conditionaly but still why should other programs even have to decide whether to load .bashrc or not)


Here is how i recommend to set up your configuration files to be less confusing.

Create a ~/.bash_profile file and put the following lines (and only these lines):

[ -f "$HOME/.profile" ] && source "$HOME/.profile"
[ -f "$HOME/.bashrc" ] && source "$HOME/.bashrc"

The deal with .bash_profile is that it is the first file bash will look for. If it exists it will no longer look for .profile.

Now if bash is started as an interactive login shell it will read the following files:

  1. .bash_profile
  2. .profile
  3. .bashrc

and if bash is started as an interactive non-login shell:

  1. .bashrc

You see that .bashrc is always read. And .profile is read additionally if it is a login shell.

And all other programs which want to just read .profile can do so without having .bashrc mixed in.

Now put bash specific settings .bashrc. All the rest in .profile. For example PS1 and HISTCONTROL goes in .bashrc while PATH and LC_ALL goes in .profile

Your RVM variable should go in .profile. It will take effect after a logout and login.


more information

http://www.gnu.org/software/bash/manual/bashref.html#Bash-Startup-Files

https://www.baeldung.com/linux/interactive-non-interactive-login-non-login-shells

https://www.baeldung.com/linux/bashrc-vs-bash-profile-vs-profile

https://unix.stackexchange.com/questions/170493/login-non-login-and-interactive-non-interactive-shells

https://unix.stackexchange.com/questions/38175/difference-between-login-shell-and-non-login-shell

Differentiate Interactive login and non-interactive non-login shell

note that some texts above say some things which contradict what i wrote above. in all cases i am of the opinion that my opinion is the more correct one.

3
  • 1
    mywiki.wooledge.org/DotFiles explains some history of why it is like it is. The main reason for this issue with rvm though is that rvm puts code, that is meant to be in ~/.bashrc in the first place, in the profile instead. The fault is on rvm.
    – geirha
    Jul 25, 2012 at 7:56
  • As per @geirha they should have used ~/.profile
    – sanmai
    Apr 28, 2016 at 0:59
  • The rationale is that the profile script can control the evaluation of .bashrc relative to what it needs to do. If the interactive shell always read .bashrc should that be before or after .profile? What if you want to set up some things in .bashrc which .profile takes for granted? And at the same time you want some things in .bashrc to rely on something set up by .profile? Neither loading order will satisfy both scenarios.
    – Kaz
    Aug 4, 2017 at 8:15
16

This is neither a bad design decision, nor a bug, nor an expected behavior of shells and terminals

It is merely an unfortunate default value of a per-profile configuration option in Gnome Terminal, which you can easily fix.

  1. Go to Edit -> Profile Preferences.

  2. Select the Title and Command tab.

  3. Notice how the Run command as login shell checkbox is unchecked! Check it.

That's it. If you do this to the Default profile, or to whatever profile is configured to be used when making new terminals, you get a login shell.

I'm guessing that under the hood, this option probably causes it to pass the -l option to the shell.

0

I had the same question, and found a solution: Simply use SSH for a real login shell!

1. As superuser, create a dedicated rvm system user for complete isolation, and assign a password:

sudo su

useradd -m rvmuser

passwd rvmuser

2. Install dependencies so that rvm can build rubies without asking for the superuser password:

apt-get install curl gawk libreadline6-dev libssl-dev libyaml-dev libsqlite3-dev sqlite3 autoconf libgdbm-dev libncurses5-dev automake bison libffi-dev

3. SSH into localhost for a real login shell (you may have to apt-get install ssh)

ssh rvmuser@localhost

4. Install rvm

\curl -sSL https://get.rvm.io | bash -s stable

5. Log out and back in again so that all rvm functions are loaded

exit

ssh rvmuser@localhost

6. Use rvm :)

0

It is common to when using bash to place the profile initialization in .bash_profile, which is read only by bash on login, whereas other shells have historically shared .profile. This allows you to place bash-specific commands in .bash_profile.

Use of the following is commonly done to pull in the aliases that are defined in .bashrc:

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
    . ~/.bashrc
fi

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .