Shell Scripts

Introduction

Ok, so we are getting a handle on variables and our environment however performing a complete listing (ls -a) reveals several login and logoff scripts (e.g. .bashrc, .profile, .logoff etc) so where do we optimally set up our environment as you can perform session initialization in several places?  (BTW – for those of you with Macs, you can open a terminal from utilities and look at the Mac version).

The bash man page cites the following (Note I edited/removed some information to render it more accessible):

When bash is invoked as an interactive login shell,  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. (The --noprofile option may be used when the shell is started to inhibit this behavior.)

When an interactive shell that is not a login shell is started, bash reads and executes commands from /etc/bash.bashrc and ~/.bashrc, if these files exist. (This may be inhibited by using the --norc option. The --rcfile file option will force bash to read and execute commands from file instead of/etc/bash.bashrc and ~/.bashrc.)

Ok so now the introduction of login and non-login shells probably obfuscated this even further however in a nutshell,  .profile is executed for login shells while .bashrc is executed for non-login shells.  This means that .profile is executed to configure the new login terminal only once (i.e. when you login and whereas .bashrc could be run several times if you start another bash instance (e.g. typing /bin/bash in a terminal).  For our purposes they are both run when we start a new

What is a login or non-login shell?

When you login (type username and password) via console, either sitting at the machine, or remotely via ssh: .bash_profile is executed to configure your shell before the initial command prompt.

But, if you’ve already logged into your machine and open a new terminal window (xterm) inside Gnome or KDE, then .bashrc is executed before the window command prompt. .bashrc is also run when you start a new bash instance by typing /bin/bash in a terminal.

Why two different files?

Say, you’d like to print some lengthy diagnostic information about your machine each time you login (load average, memory usage, current users, etc). You only want to see it on login, so you only want to place this in your .bash_profile. If you put it in your .bashrc, you’d see it every time you open a new terminal window.

Mac OS X — an exception

An exception to the terminal window guidelines is Mac OS X’s Terminal.app, which runs a login shell by default for each new terminal window, calling .bash_profile instead of .bashrc. Other GUI terminal emulators may do the same, but most tend not to.

Recommendation

Most of the time you don’t want to maintain two separate config files for login and non-login shells — when you set a PATH, you want it to apply to both. You can fix this by sourcing .bashrc from your.bash_profile file, then putting PATH and common settings in .bashrc.
To do this, add the following lines to .bash_profile:

if [ -f ~/.bashrc ]; then
   source ~/.bashrc
fi

Now when you login to your machine from a console .bashrc will be called.

Leave a Reply