What Happens When You Invoke Bash by Cory Aitchison
For a little while now I have been bothered when I login or launch a new shell. I say I have been bothered because, while I was dimly aware that bash was parsing some files (namely /etc/profile and ~/.bashrc), I wanted to know more. Also, on SUSE LINUX, the engineering teams have added some comments to /etc/profile that suggest you not make changes in that file but rather make those changes in /etc/profile.local. So as the title indicates this article is about what happens when bash is invoked specifically on SUSE Linux.
I'll start by providing a little background. As many of you are no doubt aware, the login shell is defined in /etc/passwd. If you perform a default install of SUSE LINUX your new users will be set up to use the bash shell. For more information on the glorious bash shell, I refer you to the bash website (http://www.gnu.org/software/bash/bash.html).
After doing a little digging into the bash man page I found out that there are basically two ways to invoke bash: interactively and non-interactively. From the man page:
When an interactive shell that is not a login shell is started, bash reads and executes commands from ~/.bashrc, if that file exists.
and
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.
The first case is pretty simple. When you invoke bash interactively, which is basically whenever you launch a shell and you are not logging in, ~/.bashrc is the only file that has the potential to be parsed directly by bash. I added the caveat that is has the potential to be parsed because if the file does not exist or is not readable it is not parsed. As I go forward in the article I will not make the above caveat unless it become very important that I do so again.
The second case, when a user logs in, is much more interesting. On SUSE Professional 9.3 there are at least 10 files that are searched for and parsed upon login. When I started researching this article I thought there were 3 and as it turns out most users will only care about 2 or 3 of these files anyway but I was surprised to see how many shell scripts bash goes through.
I am not going to discuss all the files that bash looks for, but rather I am going to talk about the main ones, the order in which they are parsed, and what IMVHO (in my very humble opnion) should be done in each of the files.
I plan to discuss the following files: /etc/profile Provided by SUSE Linux /etc/profile.local Referenced by the /etc/profile file provided as part of SUSE Linux ~/.profile Provided by SUSE Linux ~/.bashrc Provided by SUSE Linux
As stated above when bash is invoked interactively it starts out by parsing /etc/profile. In SUSE Linux /etc/profile also sources (to source a file basically means execute it) /etc/profile.local and ~/.bashrc in that order. There are several files that end up getting sourced while /etc/profile is parsed but /etc/profile.local and ~/.bashrc are the really important ones.
After bash has parsed /etc/profile it then looks in the users home directory for one of three files, namely: ~/.bash_profile, ~/.bash_login, and ~/.profile. Bash looks for these files in order and as soon as it find one that is readable it parses that file and stops looking for the other ones. That is, if a user has all three files in their home directory the only one that will get parsed in ~/.bash_profile. This is a confusing but important point.
At a high level the files are parsed as follows:
The first file that is parsed in /etc/profile. The bash man page describes this file as containing âThe systemwide initialization file, executed for login shellsâ?. So this is the main file that contains a lot of the setup for bash's behavior. On SUSE Linux it is recommended that you not edit this file. The reason for this is that it is distributed by Yast as part of a package (aaa_base) and if that package is modified then any changes you have made will be lost. Instead it is recommended that administrators edit the file /etc/profile.local. The version of /etc/profile will source /etc/profile.local so any changes you make in /etc/profile.local will be appropriately picked up.
Usually administrators put things into /etc/profile.local that all users will need on a system. So it would be normal to see path entries, bash variable setting (i.e., export CVS_RSH=ssh), etc in /etc/profile.local. There are several path settings that are already dealt with in /etc/profile so /etc/profile.local could be kept fairly small.
The other nice thing that SUSE Linux's /etc/profile does for you is to source ~/.bashrc. ~/.bashrc is guaranteed to be parsed when an interactive shell is launched but this is not when a non-interactive shell is launched. Most users will source ~/.bashrc in their ~/.profile file but the SUSE engineers have taken care of this for you.
~/.bashrc should contain a users specific requirements for bash. The a typical ~/.bashrc file may look like this:
# .bashrc # User specific aliases and functions export JAVA_HOME=~/usr/local/java/current #export JBOSS_HOME=~/usr/local/jboss PATH=./:$JAVA_HOME/bin/:$PATH:/usr/sbin/:~/bin:/usr/local/ant/bin:/sbin export CVS_RSH=ssh alias rm='rm -i' alias cp='cp -i' alias mv='mv -i' # Source global definitions if [ -f /etc/bashrc ]; then . /etc/bashrc fi export CCM_HOME=/usr/local/ccm export PATH=$PATH:$CCM_HOME/bin #Messing Around (mplayer ~/tmp/giggle.wav > /dev/null 2>&1 &)
So I have set up a couple of aliases so I don't accidentally mess up my system and there are some setting for various programs that I need, but it is not too complex.
After /etc/profile is parsed (and remember on SUSE Linux it is /etc/profile that sources /etc/profile.local and ~/.bashrc) bash start looking for a users local settings. Again, bash looks for ~/.bash_profile, ~/.bash_login, and ~/.profile in order and when it finds one the rest are ignored. By default, when a new user is created on SUSE Linux their home directory contains a .profile file. So bash will be unsuccessful in finding ~/.bash_profile, and ~/.bash_login and will simply execute ~/.profile.
As will the other files outlined above you can put what ever you want in ~/.profile but you would usually stick to stuff that is specific for your user. ~/.profile is usually only run once, when you login so setting that go in there should only need to be run once.
At a high level these are the files that are parsed by bash upon launch, and a brief opinion as to what should be placed in each. As with any paper I post for Novell, you the reader are welcome to email me at caitchison@novell.com to correct my and I will make updates as necessary.
A user sent in a message asking about how to limit the number of times entries in your ~/.profile files are read by bash. I suggested the following:
#Start of .profile if test -z "$DOT_PROFILE_READ" ; then export PATH=$PATH:<new path entry> fi . . . if test -z "$DOT_PROFILE_READ" ; then readonly DOT_PROFILE_READ=true export DOT_PROFILE_READ fi #end of .profile
© 2008 Novell, Inc. All Rights Reserved.