Fall 2013 - September to December 2013 - Updated 2018-02-22 09:57 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
.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.
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 .bashrc
PS1
string, described below, as a second lineThose are the only two lines that must be in your .bashrc
file.
Your
.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.
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
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 (hasPS1
set 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 .bashrc
IndexDo 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 prompt
Your .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!