Configure gnome-terminal to start bash as a login shell, doesn't read .bashrc

46

Solution 1

Yes, 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

Read the bash manual about startup files for more details.

Personally, I think that this behaviour is strange and I have not yet found a rationalization for this design decision.


Some explanation of the terminology:

  • An interactive shell is a shell with which you can interact, that means you can type commands in it. Most shells you will use are interactive shells.
  • A non-interactive shell is a shell with which you cannot interact. Shell scripts run inside 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.

Most shells you see are interactive non-login shells. This is especially true if you are running a graphical environment like gnome, because then gnome is the "login shell". Any bash session started inside gnome is a non-login shell. If you want to see a real interactive login shell then go to a virtual console (using Ctrl+Alt+F1) and then log in using your username and password. That is a real interactive login bash shell. You can go back to the graphical shell using Ctrl+Alt+F7.

There is an option --login which will make bash behave as if it is a login shell even if started after your have logged in. Configuring gnome-terminal to start bash as a login shell means it will start bash using the --login option.


Usually you want bash to always read ~/.bashrc in an interactive shell. Here is how I recommend to do that:

Create a ~/.bash_profile file. If bash is started as a login shell it will first look for ~/.bash_profile before looking for ~/.profile. If bash finds ~/.bash_profile then it will not read ~/.profile.

Put the following lines in ~/.bash_profile:

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

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 should put stuff which is bash specific in ~/.bashrc and stuff which is not bash specific in ~/.profile. For example PATH goes in ~/.profile and HISTCONTROL goes in ~/.bashrc.

Note that ~/.profile is not bash specific. Other text based shells (for example sh or ksh) and graphical shells (gnome) also read ~/.profile. That is why you should not put bash specific stuff in ~/.profile.

Solution 2

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.

Share:
46

Related videos on Youtube

JN_newbie
Author by

JN_newbie

Updated on September 18, 2022

Comments

  • JN_newbie
    JN_newbie over 1 year

    I have wrote to the code of displaying(hide/show) the fields when checkbox is checked. The javascript is below

    if(document.getElementById("checkBox") != null){
                if(!document.getElementById("checkBox").checked){
                    document.getElementById("displayField1").style.display = "none";
                    document.getElementById("displayField2").style.display = "none";
                    document.getElementById("displayField3").style.display = "none";
                }else{
                    document.getElementById("displayField1").style.display = "";
                    document.getElementById("displayField2").style.display = "";
                    document.getElementById("displayField3").style.display = "";
                }
            }
    

    In JQuery

    $(document).ready(function(){
    if ($('#checkBox').is(':checked')) {
                        $("#displayField1").show();
                        $("#displayField2").show();
                        $("#displayField3").show();
                    } else {
                        $("#displayField1").hide();
                        $("#displayField2").hide();
                        $("#displayField3").hide();
                    } 
            });
    

    It is working fine in IE8 but not in IE7, after the page is refreshed. I have tried jquery as well but still facing this issue.

    • John Dvorak
      John Dvorak over 11 years
      May I suggest "don't support IE7"?
    • polin
      polin over 11 years
      Have you tried on other browsers like firefox or chrome
    • John Dvorak
      John Dvorak over 11 years
      @polin "it is working fine in IE8"
    • JN_newbie
      JN_newbie over 11 years
      @polin. It is working fine in IE8, firfox. But not in IE7
  • richsage
    richsage almost 12 years
    +1. Thanks, this was driving me up the wall... :-)
  • geirha
    geirha almost 12 years
    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.
  • sanmai
    sanmai about 8 years
    As per @geirha they should have used ~/.profile
  • Kaz
    Kaz almost 7 years
    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.