The UNIX environment can be highly customized by manipulating the settings of the shell. Commands can be made to change their default behavior, environment variables can be redefined, the initialization scripts can be altered to obtain a required shell environment. This chapter discusses different ways and approaches for customizing the environment.
Common Environment Variables
Command Aliases (bash and korn)
Command History Facility (bash and korn)
In-Line Command Editing (bash and korn)
Miscellaneous Features (bash and korn)
The Initialization Scripts
The UNIX shell is both an interpreter as well as a scripting language. An interactive shell turns noninteractive when it executes a script.
Bourne Shell – This shell was developed by Steve Bourne. It is the original UNIX shell. It has strong programming features, but it is a weak interpreter.
C Shell – This shell was developed by Bill Joy. It has improved interpretive features, but it wasn’t suitable for programming.
Korn Shell – This shell was developed by David Korn. It combines best features of the bourne and C shells. It has features like aliases, command history. But it lacks some features of the C shell.
Bash Shell – This was developed by GNU. It can be considered as a superset that combined the features of Korn and C Shells. More importantly, it conforms to POSIX shell specification.
We already mentioned a couple of environment variables, such as PATH and HOME. Until now, we only saw examples in which they serve a certain purpose to the shell. But there are many other UNIX utilities that need information about you in order to do a good job.
What other information do programs need apart from paths and home directories? A lot of programs want to know about the kind of terminal you are using; this information is stored in the TERM variable. The shell you are using is stored in the SHELL variable, the operating system type in OS and so on. A list of all variables currently defined for your session can be viewed entering the env command.
The environment variables are managed by the shell. As opposed to regular shell variables, environment variables are inherited by any program you start, including another shell. New processes are assigned a copy of these variables, which they can read, modify and pass on in turn to their own child processes.
The set statement display all variables available in the current shell, but env command displays only environment variables. Note than env is an external command and runs in a child process.
There is nothing special about the environment variable names. The convention is to use uppercase letters for naming one.
The Common Environment Variables
The following table shows some of the common environment variables.
List of directories searched by cd when used with a non-absolute pathname
We will now describe some of the more common ones.
The command search path (PATH):The PATH variable instructs the shell about the route it should follow to locate any executable command.
Your home directory (HOME): When you log in, UNIX normally places you in a directory named after your login name. This is called the home directory or login directory. The home directory for a user is set by the system administrator while creating users (using useradd command).
mailbox location and checking (MAIL and MAILCHECK): The incoming mails for a user are generally stored at /var/mail or /var/spool/mail and this location is available in the environment variable MAIL. MAILCHECK determines how often the shell checks the file for arrival of new mail.
The prompt strings (PS1, PS2): The prompt that you normally see (the $ prompt) is the shell’s primary prompt specified by PS1. PS2 specifies the secondary prompt (>). You can change the prompt by assigning a new value to these environment variables.
Shell used by the commands with shell escapes (SHELL): This environment variable specifies the login shell as well as the shell that interprets the command if preceded with a shell escape.
Variables used in Bash and Korn
The Bash and korn prompt can do much more than displaying such simple information as your user name, the name of your machine and some indication about the present working directory. Some examples are demonstrated next.
$ PS1=‘[PWD] ‘
[/home/srm] cd progs
Bash and Korn also support a history facility that treats a previous command as an event and associates it with a number. This event number is represented as !.
$ PS1=‘[!] ‘ $ PS1=‘[! $PWD] ‘
 _ [42 /home/srm/progs] _
$ PS1=“\h> “ // Host name of the machine
Bash and korn support the use of aliases that let you assign shorthand names to frequently used commands. Aliases are defined using the alias command. Here are some typical aliases that one may like to use:
alias lx='/usr/bin/ls -lt'
alias l='/usr/bin/ls -l'
You can also use aliasing to redefine an existing command so it is always invoked with certain options. For example:
alias cp=”cp –i”
alias rm=”rm –i”
Note that to execute the original external command, you have to precede the command with a \. This means that you have to use \cp file1 file2 to override the alias.
The alias command with a argument displays its alias definition, if defined. The same command without any arguments displays all aliases and to unset an alias use unalias statement. To unset the alias cp, use unalias cp
Bash and Korn support a history feature that treats a previous command as an event and associates it with an event number. Using this number you can recall previous commands, edit them if required and reexecute them.
The history command displays the history list showing the event number of every previously executed command. With bash, the complete history list is displayed, while with korn, the last 16 commands. You can specify a numeric argument to specify the number of previous commands to display, as in, history 5 (in bash) or history -5 (korn).
By default, bash stores all previous commands in $HOME/.bash_history and korn stores them in $HOME/.sh_history. When a command is entered and executed, it is appended to the list maintained in the file.
Accessing previous commands by Event Numbers (! and r)
The ! symbol (r in korn) is used to repeat previous commands. The following examples demonstrate the use of this symbol with corresponding description.
$ !38 The command with event number 38 is displayed and executed (Use r 38 in korn)
$ !38:p The command is displayed. You can edit and execute it
$ !! Repeats previous command (Use r in korn)
$ !-2 Executes command prior to the previous one ( r -2 in korn)
Executing previous commands by Context
When you don’t remember the event number of a command but know that the command started with a specific letter of a string, you can use the history facility with context.
Example: $ !v Repeats the last command beginning with v (r v in korn)
Substitution in previous commands
If you wish to execute a previous command after some changes, you can substitute the old string with new one by substitution.
If a previous command cp progs/*.doc backup is to be executed again with doc replaced with txt,
$ !cp:s/doc/txt in bash
$ r cp doc=txt in korn
$_ is a shorthand feature to represent the directory used by the previous command.
$ mkdir progs
Now, instead of using cd progs, you can use,
$ cd $_
The History Variables
The command history will be maintained in default history files viz.,
.bash_history in Bash
.sh_history in Korn
Variable HISTFILE determines the filename that saves the history list. Bash uses two variables HISTSIZE for setting the size of the history list in memory and HISTFILESIZE for setting the size of disk file. Korn uses HISTSIZE for both the purposes.
In-Line Command Editing
One of the most attractive aspects of bash and korn shells is their treatment of command line editing. In addition to viewing your previous commands and reexecuting them, these shells let you edit your current command line, or any of the commands in your history list, using a special command line version of vi text editor. We have already seen the features of vi as a text editor and these features can be used on the current command line, by making the following setting:
set –o vi
Command line editing features greatly enhance the value of the history list. You can use them to correct command line errors and to save time and effort in entering commands by modifying previous commands. It also makes it much easier to search through your command history list, because you can use the same search commands you use in vi.
Miscellaneous Features (bash and korn)
Using set –o
The set statement by default displays the variables in the current shell, but in Bash and Korn, it can make several environment settings with –o option.
File Overwriting(noclobber): The shell’s > symbol overwrites (clobbers) an existing file, and o prevent such accidental overwriting, use the noclobber argument:
set –o noclobber
Now, if you redirect output of a command to an existing file, the shell will respond with a message that says it “cannot overwrite existing file” or “file already exists”. To override this protection, use the | after the > as in,
head –n 5 emp.dat >| file1
Accidental Logging out (ignoreeof):The [Ctrl-d] key combination has the effect of terminating the standard input as well as logging out of the system. In case you accidentally pressed [Ctrl-d] twice while terminating the standard input, it will log you off! The ignoreeof keyword offers protection from accidental logging out:
set –o ignoreeof
But note that you can logout only by using exit command.
A set option is turned off with set +o keyword. To reverse the noclobber feature, use
set +o noclobber
The ~ acts as a shorthand representation for the home directory. A configuration file like .profile that exists in the home directory can be referred to both as $HOME/.profile and ~/.profile.
You can also toggle between the directory you switched to most recently and your current directory. This is done with the ~- symbols (or simply -, a hyphen). For example, either of the following commands change to your previous directory:
cd ~- OR cd –
The Initialization Scripts
The effect of assigning values to variables, defining aliases and using set options is applicable only for the login session; they revert to their default values when the user logs out. To make them permanent, use certain startup scripts. The startup scripts are executed when the user logs in. The initialization scripts in different shells are listed below:
.profile (Bourne shell)
.profile and .kshrc (Korn shell)
.bash_profile (or .bash_login) and .bashrc (Bash)
.login and .cshrc (C shell)
When logging into an interactive login shell, login will do the authentication, set the environment and start your shell. In the case of bash, the next step is reading the general profile from /etc, if that file exists. bash then 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. If none exists, /etc/bashrc is applied.
When a login shell exits, bash reads and executes commands from the file, ~/.bash_logout, if it exists.
The profile contains commands that are meant to be executed only once in a session. It can also be used to customize the operating environment to suit user requirements. Every time you change the profile file, you should either log out and log in again or You can execute it by using a special command (called dot).
$ . .profile
The rc File
Normally the profiles are executed only once, upon login. The rc files are designed to be executed every time a separate shell is created. There is no rc file in Bourne, but bash and korn use one. This file is defined by an environment variable BASH_ENV in Bash and ENV in Korn.
Korn automatically executes .kshrc during login if ENV is defined. Bash merely ensures that a sub-shell executes this file. If the login shell also has to execute this file then a separate entry must be added in the profile:
The rc file is used to define command aliases, variable settings, and shell options. Some sample entries of an rc file are
alias cp=“cp –i”
alias rm=“rm –i”
set –o noclobber
set –o ignoreeof
set –o vi
The rc file will be executed after the profile. However, if the BASH_ENV or ENV variables are not set, the shell executes only the profile.
In this chapter, we looked at the environment-related features of the shells, and found weaknesses in the Bourne shell. Knowledge of Bash and Korn only supplements your knowledge of Bourne and doesn’t take anything away. It is always advisable to use Bash or korn as your default login shell as it results in a more fruitful experience, with their rich features in the form of aliases, history features and in-line command editing features.