Winter 2019 - January to April 2019 - Updated 2018-02-22 10:02 EST
Shells have a number of options and settings that affect how they work. You can also define shell aliases and functions to create your own command names. You can change any of these at any time, but the settings are not saved. The settings only last until the shell exits, and they aren’t always passed on to new shells.
To make your settings apply to every shell, you put the settings in profile or start-up files. Shells read these files when they first start to load the settings you want.
The two profile files you need to create for this course are
.bash_profile and .bashrc and this file will explain what to put in
each of these new files.
You can always change any settings after the shell is running, but unless you also change the settings saved in your start-up files, the settings will be lost when the current shell exits.
All shell startup files are kept in your HOME directory, which is where
cd takes you without arguments. Your HOME directory is also usually
available in the environment variable $HOME.
When you type in your user name (userid) and password to log in, the system encrypts your password and compares it against the encrypted password in the password files. If they match, you are allowed to log in.
At log-in time, the system sets your current directory to be the HOME
directory listed for your account in the password file. An initial
environment is prepared (e.g. containing a system default PATH).
For a text command-line (terminal or console) log in, the shell specified
in the password file is executed. (This shell is usually /bin/bash.)
For a graphical log-in, a window manager is started and your Desktop is initialized for display.
If your login shell is /bin/bash, the BASH process reads (“sources”)
some system start-up files such as /etc/profile and /etc/bash.bashrc
that may set system defaults for various shell settings.
Next, a login shell looks in your home directory for more start-up files
such as .bash_profile or .bash_login that you can create and use to
alter the system defaults. (See man bash for the full list.) You can
create your own initialization files to customize your environment and
terminal settings.
Some systems give default .bash_login and .bash_logout files when
you create a new account. The default files are copied from a system
directory such as /etc/skel. If you don’t have these files, you can
create them yourself.
Your instructor may have removed all default start-up files from your system, so as not to confuse you as to what a “normal” system looks like.
There are different start-up files for different types of shells. We need to understand the terms Login Shell and Interactive Shell.
A Login Shell used to be the first shell you got when you logged in to a Unix system. The system treated this shell specially, since it was your first connection to the machine. A Login Shell got its own start-up file, from where it would read shell options and other settings.
The original Bourne shell Login Shell start-up file was named .profile.
A BASH login shell first tries to find the file .bash_profile, then
falls back to using the traditional .profile file. It does not read
your .bashrc file.
The second (and subsequent) shells you got after you had already logged in were not Login Shells. When these non-login shells started up, they read a different start-up file.
A BASH non-login shell tries to find the file .bashrc from which to
read settings when it starts up. It does not read your .bash_profile.
You are most familiar with using a shell to find and run commands interactively with a keyboard and screen, but shells also run non interactively when running without a keyboard and/or screen. A file transfer program (e.g. WinSCP, FileZilla, SCP) might log in to your system using your account and a non-interactive shell to transfer files for you.
A BASH shell that is not interactive still reads the .bashrc file when
it starts up. It does not read .bash_profile (because it is not a
Login Shell).
When a file transfer program logs in to your account to transfer files, it
does not expect your account to start producing output. Output from your
account will corrupt the file transfer. This means your .bashrc file
must not generate any visible output when run by a non-interactive shell.
Your
.bashrcfile must not produce any output when read by a non-interactive shell. File transfer programs will fail if your.bashrcfile produces output that corrupts the file transfer.
On modern Unix systems with a GUI interface, you may be logged in without using any visible shell at all, so the concept of Login Shell has lost its clear meaning. It may be true that every terminal window you start up using the GUI is treated as a Login Shell (MacOSX does this), or it may treat those terminal windows as ordinary shells.
This lack of clear meaning for Login Shell leads to confusion as to where
to put your shell settings. Do you use .bash_profile or do you use
.bashrc? The solution is to use both, to handle both cases, but to
make the .bash_profile file refer to the .bashrc file so that all
the settings are made in only the .bashrc file.
Your profile files are not re-read by your current shell after you edit them – you have to tell your current shell to re-read the file to make the new content take effect in the current shell, e.g. type
source ./.bashrc
.bash_profile – only one lineIndexCreate (if necessary) and put only one single line in your .bash_profile file:
source ./.bashrc
That is the only line that should be in your .bash_profile. That line
sends the shell to use the .bashrc for all settings. We will put all
shell settings for all shell uses, Login, Interactive, etc., in the one
.bashrc file. Do not put any other lines in your .bash_profile.
.bashrc – all other settingsIndexBy using source ./.bashrc in .bash_profile, we ensure that every
shell, Login or not, reads the .bashrc file when it first starts.
The .bashrc is the file that we create (if necessary) and into which
we put all shell settings. Any settings you define in .bashrc
will apply to all BASH shells.
(If you want to start a BASH shell that does not read any start–up
files, use the --norc option when you start it.)
You are only required to create this file with two lines, each described
below, in your .bashrc in this course:
# exit if not interactive, described
below, must be the first line in .bashrcPS1 string, described below, as a second lineThose are the only two lines that must be in your .bashrc file.
Your
.bashrcfile must not produce any output when read by a non-interactive shell. File transfer programs will fail if your.bashrcfile produces output that corrupts the file transfer.
To be safe, the first executable line of your .bashrc must be this one:
[ -z "${PS1-}" ] && return # exit if not interactive
Note the required use of spaces around all of the words in the above line.
This line is one of the two required lines that must be in your
.bashrc in this course.
Non-interactive shells (e.g. run by file transfer programs using your account) do not set a prompt, and these shells must not generate prompts or any output when they run. Programs transferring files to/from your account depend on non-interactive shells executing without generating any unexpected output.
Do not set the
PS1prompt string in any start-up file unless it is already set, indicating an interactive shell. Do not produce any output in any start-up file unless the shell is interactive (hasPS1set non-empty).
To prevent the rest of a .bashrc from running if the shell is not
interactive, make sure this line is at the start of the file (make sure
you type this exactly as shown, including all the spaces):
[ -z "${PS1-}" ] && return # exit if not interactive
The above line will check for the existence of a prompt and skip the rest
of the .bashrc if the shell is not being used interactively. The result
will be no unexpected output when a shell is used non-interactively.
Do not insert any lines line that generate output above this line;
this line should be at the top of the file.
You can test your shell’s non-interactive output by using ssh to execute
a remote command that produces no output, such as true or cd, and
making sure that no output appears after you enter your password:
(If you are asked to accept a sever host key, say yes below.)
$ ssh localhost true
*** COURSE LINUX SERVER ***
user@localhost's password:
$
Above, there is no unexpected output from the remote non-interactive shell. The remote system produces no spurious output. Below is a system that is broken and file transfers will fail:
$ ssh localhost true
*** COURSE LINUX SERVER ***
user@localhost's password:
Welcome back gracious Lord of All.
$
The above “Welcome” line is output from an echo command inside a
.bashrc. The non-interactive output will cause file transfer programs
to fail. Remove the line that produces this output or put it after
the exit if not interactive command given to you, above:
[ -z "${PS1-}" ] && return # exit if not interactive
echo "Welcome back gracious Lord of All."
PS1='YesMaster\$ '
If you fully log in and the shell is interactive, the .bashrc runs
normally (a prompt is defined) and the echo generates the expected
output:
$ ssh localhost
*** COURSE LINUX SERVER ***
user@localhost's password:
Welcome back gracious Lord of All.
YesMaster$ exit
$
PS1 PromptIndexSetting your PS1 prompt is the only other required line that must be
in your .bashrc file. Having part of your current working directory
visible in your shell prompts is helpful. Setting this PS1 prompt
does only that:
PS1='[\W]\$ ' # include only the current directory in your shell prompt
You can optionally include more fields in the prompt, if you wish:
PS1='[\u@\h \W]\$ ' # optional: include user, host, and PWD in shell prompt
Put the one PS1 prompt setting statement somewhere below (after) the
# exit if not interactive line, described above that must be the first
line in the file. RTFM in man bash to learn what all the backslash
escape characters mean in the PS1 variable prompt string.
There are many more!
.bash_profile and .bashrcIndexDo not set any options or aliases that you do not understand!
If you don’t know the meaning of a setting, don’t use it. You can RTFM
in the bash man page for all BASH settings.
Create these files in your HOME directory, if necessary. (Some systems will have already created these files for you.)
.bash_profile – in this course, this file must be only one line long:
source ./.bashrc.bashrc – in this course, this file must contain at least these two lines:
[ -z "${PS1-}" ] && return # exit if not interactive
PS1='[\W]\$ ' # include only the current directory in your shell promptYour .bashrc file must not produce any output when read by a
non-interactive shell. File transfer programs will fail if your
.bashrc file produces output that corrupts the file transfer.
Your profile files are not re-read by your current shell after you
edit them – you have to tell your current shell to re-read the file
to make the new content take effect in the current shell, e.g. type
source ./.bashrc
Do not set the PS1 prompt string in any start-up file unless
it is already set, indicating an interactive shell. Do not produce
any output in any start-up file unless the shell is interactive (has
PS1 set non-empty). The exit if not interactive line ensures this.
You can choose any PS1 prompt string you like.
You might read the optional material: BASH Settings for System Administrators. This material is not required for this course; it is optional.
Do not set any options or aliases that you do not understand!