UNIX: Customizing Your Environment

Changing the World around You

Unix is popular with many users, especially programmers, because of the ease with which you can customize your computing environment. Within Unix you can create commands, configure various settings to make the environment suit your tastes and needs, and create helpful shortcuts for accomplishing complex tasks. These feats are primarily accomplished by special files which are automatically executed each time you login. The names of the files may vary depending on the type of shell you are using. For the C shell, they are the .login and .cshrc files. For the Korn shell, the file of primary importance is the .profile file.

To manipulate these files with any proficiency, you need to be acquainted with at least one Unix editor. The simplest of these is probably Pico; vi and emacs editors offer greater power. Any editor will be sufficient for our purposes. In addition, this handout presumes that you have a basic working knowledge of Unix. You should be familiar with hierarchical directory structures and have mastered basic Unix commands (ls, cd, chmod, cat, more, etc.). You should also be familiar with some more advanced concepts, such as pipes and redirection. You can find discussions of the above, respectively, in the Unix: Getting Started (cus01) and Unix: Data Tools (cus02) classes and the corresponding handouts which are available at the Training Center on the fourth floor of Hanes Hall.

Getting Acquainted with your Surroundings

The kind of shell you use is the single most important setting determining your environment. There are a variety of shells available. Each of them has different capabilities and drawbacks. The Office of Information Technology supports the C shell and the T shell, which is a modified version of the C shell. To check if you are running one of these two shells, do the following:

1. The simplest way of telling which shell you are using is by looking at your prompt: if it is a %, then you are probably using a C or T shell. If it is a $, for example, then you are using either the Bourne or Korn shell.

2. If you cannot tell from the prompt, then at the prompt, type finger yourid; where yourid is your actual user id. This should produce an output like the following (it may look somewhat different depending on your configuration):

Login  name:  leon                                                In  real  life:  Sandy  Cash
Office:  402  Hanes,  962-0212                          Home  phone:  555-4554
Directory:  /home/leon                                      Shell:  /bin/csh
On  since  Apr  16  21:33:05  on  ttyp2  from  xyplex42.oit.unc
Project:
Plan:

The field which concerns us is the Shell field: this tells us what shell runs when we login to the system. In my case, when I use Gibbs I use a C shell indicated by csh. Other possible shell indicators are tcsh for T shell, ksh for Korn shell, and sh for Bourne shell

3. Or, type at the prompt: echo $shell. This will print out the shell currently being run.

Modifying your Surroundings

Where are the control panels?

Sorry, but there aren¢ € ™t any. Unlike using Windows or Mac operating systems, there are no convenient buttons or slider switches for changing your settings. Instead, you have to type the proper command for each setting. Although this may make Unix seem arcane and complex, don¢ € ™t be put off by words such as “variable” and “script.” Those same qualities, which in Macintosh and Windows make it so easy also limit your options. In comparison, as a Unix user, you have access to virtually every important setting for your environment. The more you use it the less difficult it becomes.

Where are these settings stored?

Most of your settings are stored in a list of variables. These variables generally come in two varieties: shell variables and environment variables. There is one major difference: environment variables are common to every shell you initialize during your session and have global scope; shell variables are specific to the shell in which they are defined. For example, the following is a list of the environment variable settings in my Gibbs environment:

TERM=vt100n HOME=/home/leon SHELL=/bin/csh USER=leon PATH=.:/home/leon/bin:/usr/convex:/usr/ucb:/bin:/usr/bin:/usr/local/bin:/usr/X1n LOGNAME=leon SHLVL=1 PWD=/home/leon HOST=gibbs HOSTTYPE=convex PAGER=more EDITOR=vi VIRTUAL=vi DISPLAY=152.2.190.42:0.1

Each of these values is defined for every shell and process that I run during my login session. The type of value depends on the specific variable: some have numeric values, some have string values. To determine if a variable is set or defined within a particular shell, type: echo $ variable. If the variable comes back undefined in your new shell, then it is a shell based variable. If I were to type csh at the shell prompt, thereby starting up a new shell on top of my current one, the mail variable in Gibbs or Isis would be undefined in the new shell. This means that although you can assume that your environment variable values are always valid, it is a good idea whenever you start a subshell to initialize any shell variables you might need.

How do I initialize a variable?

Actually, it isn¢ € ™t that hard to assign a value to a variable. First, determine if the variable is a shell or environment variable. For environment variables, type:

%  setenv  VARIABLE    value

For shell variables, type:

%  set  variable=value

I’m getting tired of setting all these variables – isn¢ € ™t there a quicker way?

Yes, actually there is. If you type ls -a at the prompt, you¢ € ™ll notice that there is a pair of files in your account, one named .login and the other named .cshrc. Each of these is an example of a shell script (we¢ € ™ll discuss these in more detail later) containing a number of commands executed automatically upon login; among these commands are several important defining variables. The difference between the .login and .cshrc, is that the commands within the .login file are only executed when you first login, but not when you start up subsequent shells in the same session. So the .login is a good place to store environmental variables, since these will need to be reinitialized every time you start a new shell. On the other hand, for every new C shell you start all the commands in your .cshrc are executed. This makes the .cshrc a better place to store definitions for shell variables; you will not need to redefine them for every shell you start. Some environment variables, such as LOGNAME and HOST, are defined automatically, so you need not worry about these.

Path Variables

One environmental variable of great importance is the path. The path variable contains a set of directories separated by colons. When you enter a command at a Unix prompt, these directories are searched in the order specified by the path variable. The search process stops at the first occurrence of the file whose name matches the one you entered. Let’s say that you have retrieved a file from the Internet, such as gunzip (which is an executable file that uncompresses any file with a .gz extension). If we look at the path variable in our .cshrc file, we see a set of locations where we might store the gunzip file:

set path = (. ${home}/bin /usr/isis /usr/local/bin /usr/ucb /usr/bin/X11 /usr/bin /bin /etc/usr/sbin /etc ~joeuser/class)

The first entry in the path variable is “.” This tells the C-shell to begin every search in the current directory.

Next is ${home}/bin, which translates to a personal bin directory located off of the user¢ € ™s home directory. You might place the gunzip program in this directory, or you could create a directory with the mkdir command (ex. mkdir gnu). If you place the gunzip program into your newly created gnu directory, you would have to call it out by its full pathname, onyen /gnu.* Note: the “~” in is akin to ${home} and means the home directory of the onyen immediately following. Or, we could update the path variable to include this newly formed directory.

Using an Unix editor, edit the .cshrc file. Place the cursor on the line you wish to edit. Once you are on the correct line, insert the new directory. Enter the text ${home}/gnu. When you have finished entering text, return to the command mode and exit the editor saving the changes you have made.

*The Onyen is what used to be called the UserID. “Onyen” stands for the “Only Name You’ll Ever Need” and will eventually replace all campus login names.

What’s that percentage sign on the left for?

The percentage sign (or dollar sign, in some cases) is your prompt. Its presence simply signals that the shell is ready and waiting for your next command. You are not limited to a percentage sign, ‘though. Some people like to customize their prompts to include various pieces of information. My own prompt for my Gibbs account looks like this:

Apr  28  11:43  AM
/home/johndoe%

My prompt is actually a two-line one, with the current date, time, and working directory all displayed.

Can I create one of those cool custom prompts?

It is quite easy to modify your prompt so that it displays certain information or a custom message. The prompt information is stored in a variable, specifically the prompt (no surprise there) variable. This variable is normally initialized in the .cshrc. To change the value assigned to it, you need to edit the following line in your .cshrc: set prompt = “…%” You can display a variety of things in the prompt. In addition to the date, time, and current working directory, you can put the hostname and your onyen. Depending on the system or version of Unix you are working with, there are even some formatting commands for reverse or underline text. To display these types of information and formats, you need to include between the quotes in your prompt string one or more control characters. These characters consist of an alphabetic character preceded by a percentage sign. For example, the command in my .cshrc which produces my prompt is as follows: set prompt = “%w %t \n%d%” From right to left, the %w specifies the date in Mon DD format, the %t gives the time in twelve hour format, the \n is the “newline” character, telling the shell to begin a new line, and the %d gives the current working directory with the complete path. Note: these characters are not universal to all versions of the C shell. To get the same prompt under the standard Isis shell, you would need to type:

set prompt = “%w %D %t \n%/%” Finding out just what the proper control sequences are can be difficult and confusing. For most shells on most systems, you can pull up the shell man page by typing at the prompt: % man csh You can, of course, replace “csh” with whatever shell you are using at the time. Unfortunately, on most systems the information about the prompt setting comes fairly late in the man page. To save you the time and trouble of paging through lots of data, the table below gives some of the sequences for both Gibbs and Isis. Note : there are a few differences between the two systems.

To get: on Gibbs use: on Isis use:
working directory with path %d %/
path in ~username format %~ %~
trailing component of path %c %c
history # of last command %h %h
time in 12 hr. format %t %t
time in 24 hr. format %T %T
your onyen %n %n
shell¢ € ™s tty # %l %l
full hostname N/A %M
hostname up to first ¢ € ˜.¢ € ™ %M/%m %m

That¢ € ™s nice, but am I stuck with the same old look?

No, you can set not only the content of the prompt, but also the format. If you insert one of the following format specifiers into your prompt description, everything after it will be in the specified format. To end the format, use the corresponding character (these are usually lowercase).

To : on Gibbs use: on Isis use:
begin boldface %B %B
end boldface %b %b
begin standout (backlit) %S %S
end standout %s %s
begin underline %U %U
end underline %u %u

For example, typing this initialization: set prompt = “%U%t%u %B%n%b%” on either Gibbs or Isis should produce this prompt: 11:43 AM johndoe%

Source Command

All changes that you make in the .cshrc file will show up on your next login, and all successive logins. To use the changes you have made in your current session, use the source command, (type: source .cshrc). When you source a file, you are telling Unix to use the information in this file as the basis for any environmental definitions. Once you have sourced the updated .cshrc file, the C-shell will find and implement all your new variable definitions.

Creating your Own Commands

While the range of commands available on a Unix based system is significantly broader than those on as system such as DOS, you may still wish for a tool you simply don¢ € ™t have. For instance, you want a command to apply only to directories; or maybe you want to cycle through a series of files, adding a line to each; or you simply want to be able to page the output of a particularly lengthy listing. In these cases, and others, where the specific command or tool does not exist, you can create your own. Unix is particularly flexible in the way it allows you to create custom utilities to perform repetitive, boring, or complicated tasks.

Basic Tool Creation – Aliases

Some Unix commands are reasonably short and somewhat intuitive, but this is often not the case. Perhaps you have had to enter a command such as the following before:

%  find  /usr/local  -name  sz  -print

This command searches in the directory structure under /usr/local for a file named sz, and then, if it finds the file, the path is printed to the screen. Or, perhaps you have entered a command like the following:

%  ls  -alR  |more

This command gives a complete listing of all the files within a directory and any subdirectories, and then pages the output. Both of the preceding commands are unwieldy to type. The second one especially is the sort of command you might use quite often. In cases like these, you do not need to type the entire command every time; rather, you can create an alias for the command. An alias is a pseudonym you assign to an individual command or a series of commands. You can then execute the command(s) by simply typing the alias and pressing <enter>. The computer will execute all the commands which we assigned to the alias. The command to create an alias is as follows:

%  alias  aliasname  "command(s)"

Here the second argument should be the command(s) you wish to perform. Remember: separate multiple commands by either semicolons or pipes. The aliasname should simply be a short, easy-to-remember nickname which you will type in place of the command(s). For example:

%  alias  la  &quot;ls  -al|more&quot;

This allows me to type at the prompt la resulting in a long listing of all the files in my immediate working directory with the output paged. There is no need for me to remember all the commands or worry about including the proper switches. The computer will store these as part of the alias¢ € ™ definition. In this way I can automate the complicated tasks I find myself performing fairly often, simply by creating a different alias for each one. It’s important to assign well-thought-out names to aliases. An alias does no good if you cannot remember it! Note the alias you have just created is only defined for that login session.. To make an alias automatic for each login session, you will need to add the alias command as a line in your .cshrc file. Using the editor of your choice, open the .cshrc file, add the line alias aliasname command(s) , exit and save the file.

If I forget my aliases…?

If you find that you have created aliases and you can no longer remember their names, or perhaps you simply created so many that remembering all of them has become impossible, then you should do two things. First, you should probably do away with some of the less useful of your aliases. Aliases are really best used for particularly common or complex tasks, ones which you find yourself performing fairly often. Second, if you want to get a list of the aliases created or assigned, type: % alias with no arguments. This will return an output much like the following (but probably not as long):

back        set  back=$old;  set  old=$cwd;  cd  $back;  unset  back;  dirs
big          uncompress
bye          logout
cd            set  old=$cwd;  chdir  !*
cls          clear
job          uptime;  echo  "                USER              PID  %CPU  %MEM      SZ    RSS  TT    STAT      TIMe
k9            kill  -9
la            ls  -al|more
pine        npine
pmem        sort  +3nr  -4  +2  -3  +1  -2  /mgr/padrick/adm/pmem.prev  |  expand  -8,18,40,5s
psmem      ps  -auxc  |  sort  +4  -5nr  |  less

This is a partial listing of the aliases I generally use on my Gibbs account. Some of them are assigned for me by the system administrator, such as the aliases job and pmem. I have created the others as necessary. Some of the most common Unix commands are actually aliases to other, more difficult-to-remember commands: these include the cd, job, and back commands.

How do I remove an alias?

To remove an alias, type:

%  unalias  aliasname

Advanced Tool Creation – shell scripting

You may find in your Unix experience that creating an alias is not sufficient for you needs. You may want to make use of constructs like a control statement such as if or foreach (if statements make the execution of a command conditional to some requirement, and foreach statements perform actions on a series of files). Your answer may lie in creating a shell script. A shell script is basically a type of program, but one which does not necessarily involve knowledge of a computer language beyond the Unix commands you normally use. Consider the following:

#!/bin/csh foreach  i  (*)                 set  t=`file  $i  |awk  '{print  $2}'`                 if  ($t  ==  "directory")  then                                 echo  "$i  is  a  directory"                 endif end

This is a shell script which looks for directories. When it finds one, it simply prints out, “such-and-such is a directory.” A script like this could then be modified to perform some action only on directories; or, the type of file it looked for could be modified to data files. In any case, all of the commands in this program are normal C shell functions. Some of them are less commonly used than others; most users here at UNC have probably rarely, if ever, used a foreach or if statement. But, with shell scripts you can write very useful tools without having to know one of the more well-known languages, such as C or Prolog. Let¢ € ™s take a look at a slightly simpler script, one composed of commands you are more likely to have used:

echo  'The  current  date  is:  ' date echo  'Your  loginname  is:  ' whoami

This script will produce output like this:

The  current  date  is:   Thu  Apr  13  02:27:25  EDT  1995 Your  loginname  is:   leon

That¢ € ™s pretty neat; how do I make my own?

Creating your own shell scripts is actually quite simple. The first step is, figure out just what it is you want your script to do. In our example, let’s assume that we need a script to perform some “periodic maintenance:” cleaning out old files and storing them in a directory created for the purpose. Then, you need to decide just what commands you would use to do this normally; these are the same commands we¢ € ™ll use in our script. For this script we¢ € ™ll probably need to use a mixture of mv and rm commands. Next, call up your favorite editor and start typing your script. In this case, our script will end up looking like this:

rm  -r  junk mkdir  junk mv  *  junk

Where junk is the name of the directory you will place the cleaned out files. When you¢ € ™re done, save your script to a file, named, in this example, maint. Now as it stands, our script is not anything more than a basic text file. To make possible to execute it as a script, tell the shell that it is an executable file; do this by typing

%  chmod  u+x  maint

This allows our script file to be run just as any other program that gives the computer instructions. To actually run it, we simply type the name of the script at the prompt, in this case maint and hit <enter>. As a general rule, any scripts you create should be stored in the bin subdirectory in your home directory. Remember: this is the directory in your PATH variable set aside for programs you install in your account.

Can I have a script like this execute automatically every time I login?

Absolutely. Simply put the name of the script on a line in your .cshrc or .login. Remember, the .cshrc and .login files are really nothing more than shell scripts themselves; every line is treated as a command to be executed. When the shell sees the name of your script in either of these files, it will execute it. Make sure that if you put the script name in your .login it comes after the definition for the environment variable PATH, otherwise the shell might not know where to find the script definition.

Recycling Your Old Commands

OK, you’ve just finished typing in that monster four command pipeline. You check the output, and you realize…you need to do the exact same command again!

Oh, come on. Do I really have to type the whole command again?

Well, actually, no. Often, using Unix seems like one large typing test, where any typo spells disaster. But you can avoid the tedium of typing the same commands over and over again because Unix remembers the commands you¢ € ™ve typed in. Unix stores these commands in two variables, the history and savehist variables. The first of these, history, stores a set number of commands during the current session. At any time you can access this group of commands using a variety of shortcuts. The second variable, savehist, stores a set number of commands from your previous login session.

How do I know how many commands Unix will remember?

In your .cshrc file there will usually be a command like this:set history=50. This tells Unix to remember your last fifty commands. Each time you execute a command at the prompt, it becomes command number fifty, and the oldest command in the history is deleted. If you need to access more than your last fifty commands, you can simply change the line in your .cshrc to preserve more than fifty, to something like set history=75.

Can I see what my commands were?

Absolutely. You can see all the commands stored by simply typing at the prompt

%  history

This will display a list of every command in your history, with the history command last in the list. Beside each command will be a number, marking its position in the list. These are ordered first-to-last. To re-enter one of the commands in your history, use the following keystrokes:

Keystroke Action
!! repeat last command
!# do the numbered command (e.g., !5 does your fifth command)
!-# do the numbered command relative to you (e.g., !-5 executes the command done five back)
!x find and execute a command that began with x (e.g., !l might find a ls command you did)
!?x find the last event that contains x anywhere in the command

Using history processes in your shell

The C-shell itself has a history mechanism. You can access your last six commands, (starting backwards from your most recent entry), by using the up arrow key. These commands are kept in an editable buffer; use the arrow keys to relocate the cursor along the command line. You can then edit the command until you have it configured the way you want it. Press the <enter> to implement the command .

A Last Shell Command-Editing Trick

You can change characters in the last command you entered through use of the ^. The example below illustrates this property:

%  ls  prgram
prgram:  No  such  file  or  directory
%  ^prg^prog
-rwx--x--x    1  joeuser        nobody        85772    Dec  27  17:15      program*

As you can see, the ^ corrects the misspelled entry in the first command.