Previous Up Next

6  Prompts and Shells

6.1  What is a shell?

When you log into a Unix system you will see a bunch of text, followed by the hopefully now familiar prompt (which may be a $, or a %, or may be more complex). What you are seeing at this point, and what you will be interacting with to start all your programs is a program known as a “shell”. A shell is just a program like any other, its not really that special. In it’s simplest form all it does is display a prompt and wait for a line of input. Once you type in a line and press return it works out what program you want to run, starts that program executing, and when the program finishes and the shell has control of the terminal again it prints out its prompt, waiting for another command. The default shell used at Lancaster University is “tcsh”.

More information on tcsh can be found by googing for terms like “tcsh”. There is a wiki about the shell at:
http://www.tcsh.org/

But its advised that you at least skim this section before reading that.

Modern shells offer far more power to their user, customisable prompts, management of environment variables, running more than one program at once (see section 7.2 for more), completion of filenames for the user and flow control to help with writing shell scripts, but these topics aren’t essential for the user to understand at first, just helpful.

6.2  Name completion

One of the more useful features of modern shells is “name completion”. This is where for example you type half of a filename, or a program name in your path then press a key and it will either complete it if there is only one option or offer you the list of possible completions.

For tcsh the key that does completion is ‘^d’ (hold control, press ‘d’), you can test this by typing virtually any single character and pressing this key combination. Its worth being a little careful with this however as pressing ‘^d’ when you have just a prompt and haven’t typed anything yet will logout of the system.

6.3  Environment variables

Environment variables are simply that, they are variables (which in its simplest form means they are names associated with values), and they contain information about the environment your programs are running in.

In practise most of them can be left alone to their default states, but its worth knowing about how they work in case you want to change the way in which your sessions work. The first thing to know is how to see what’s in an environment variable.

% echo $USER

The above line runs the program echo which simply echoes its arguments back to the user’s terminal, since its argument is the environment variable $USER then it will print the contents of it, which should be your username.

The conventions with environment variables are that they are usually written in ALL_CAPITAL_LETTERS and that they have no spaces, any spaces are normally filled with underscores (‘_’). Also while being set or stored they are just written normally whenever you want to access one it must be prefixed with the $ character.

The ability to print out single environment variables isn’t very helpful without knowing what variables there are in use. Too see them all simply use this command:

% printenv

This will simply print all the current environment variables that your shell knows about, there should be about 30 or 40 of them, and most can be safely ignored, some however are useful to know about:

$USER as mentioned before contains your username.

$HOME contains the path to your home directory.

$PATH contains the path of directories to search for programs, this is covered in section 4.5.

$MAIL will point to your inbox.

$SHELL will give the path to your shell, this will probably be “tcsh”.

$TERM contains your terminal, This will probably be “xterm”.

$PAGER contains the path to the program that deals with lots of text, this will probably be “less”.

There are also a number of useful environment variables which may not be set by default, these are designed to make a user’s life easier as programs will consult these before running that type of program. These include:

$VISUAL which contains your visual (full screen) editor (see section 5) and programs that want you to edit a block of text will often simply look at the $VISUAL variable and run whatever program that contains.

$EDITOR is another variable that again should contain your editor of choice, can often be ignored as most things will only consult $EDITOR if $VISUAL isn’t set, however some things check this.

$MAILER often contains your Mail User Agent (see section 8) of choice, definitely optional.

$UAEDITOR is a very Lancaster specific option, the default editor for messages and pages in the LuBBs system (see section 13.11). It defaults to running ue and so you may wish to change it if you prefer another editor. It is worth noting that LuBBs also supports the $UAVISUAL environment variable, although it treats them both the same.

6.3.1  Changing environment variables

Environment variables are controlled by the “setenv” and “unsetenv” programs, which can add or remove environment variables (setenv can also change existing ones). Their use is fairly simple, to add a variable simply use:

% setenv VISUAL "vim"

This will set the environment variable called $VISUAL (note the lack of $ (dollar) sign when setting it) to contain the string “vim”. This means that whenever a program wants to get some text editing done for you it will spawn a copy of vim to handle it. If you prefer for example the Emacs editor you would type:

% setenv VISUAL "emacs"

Even if the $VISUAL variable is already set, this command will change it and overwrite its contents with the new information.

6.3.2  Using environment variables inside setenv

Its worth noting that when using setenv under tcsh that you have to be careful when including another variable in your current one, otherwise they don’t expand to their values properly. The classic example is changing your path to include a personal bin file. This can be done with the following line:

% setenv PATH "${HOME}/bin:${PATH}"

You’ll note that when using a variable inside setenv you need to write ${NAME_OF_VARIABLE}, essentially put it inside braces, but the $ (dollar) symbol outside.

6.4  What is a terminal?

The word “terminal” has been thrown about quite a bit as well, and at this point it probably needs definition. In the old days Unix computers (and in fact computers in general) were big giant things that you had one of, living at the centre of your network, nobody had Personal Computers on their desktops, instead they had terminals. These terminals got better and better over the years and so gained the ability to do much more, and so when you connect to an old Unix machine you need to tell it what kind of “terminal” (or these days emulated terminal) you are.

First things first is to find out what kind of terminal it thinks you are running, the following command will print out the terminal type:

% echo $TERM

Probably the answer you will get back will be the line “xterm”. An xterm is a reasonably advanced type of terminal, and it tends to mean that your cursor keys will work, however programs you run won’t be able to use colours to make things clearer (well the cent1 version of xterm can’t do colours, other Unix machines version of xterm can).

Other terminal types you’re likely to encounter include “vt100” and “xtermc”. vt100 is the classic fallback, a really basic terminal that won’t support cursor keys and may, or may not, support the F-keys. It will however support all the standard A-Z keys. xtermc on the other hand supports all the advantages of xterm (cursor keys, F-keys) adding colour support.

6.4.1  Changing your terminal

In order to change your terminal settings you need to change the environment variable TERM, this will be fully explained in sections 6.3 and 6.6.

The other thing worth understanding is the meaning of TTY, you’ll see it listed in several things (“who” for example lists the TTY the user is connected to). Basically it originally mean the port the users terminal was connected to (TTY1, TTY2, TTY3 etc...) but these days with so many terminals connecting over the network you’ll often find that TTY1-TTY7 are available only at the machine itself, if you connect over the network you a get assigned a ptty (Pseudo TTY). The TTY of ptty you get assigned isn’t really that important, its more just another way of dividing up resources among those who want them for the system.

6.5  Prompts

By now you should be quite familiar with with the default prompt on the Lancaster Unix server, which is just a single % (percent) symbol. However this prompt can be changed to contain quite a bit more useful information if you want to. In many shells it is controlled by an environment variable (see section 6.3) called $PS1 and changing this will cause the prompt to change to its contents. This applies to “sh” and “bash”, which are commonly used on Unix systems (see “man bash” for details).

The University systems however use the tcsh shell by default (see “man tcsh” for all the things this shell can do), this uses “shell variables”, similar to environment variables but only accessible by the shell, to control itself. The one that controls the main prompt is simply called “prompt” and changing the variable will change how your prompt looks. Including certain characters in the “prompt” variable gives interesting results as you can put more information in your prompt, for full details see “man tcsh”. Examples of these include:

%/ gives the current working directory.

%~ gives the current directory, but with the path to your home shown only by ‘~’.

%cN the last N characters of the path.

%m the hostname of the machine you’re logged into.

%t the time in 12 hour AM/PM format.

%T the time in 24 hour format.

%% an actual % sign.

%n your username.

%l the tty (terminal) your shell is running under.

$FOO prints the conents of shell variable $FOO.

%? prints out the return code of the last program to run, generally 0 means it ran ok, 1 means it failed somehow.

These can be combined to make your prompt more useful and informative, for example I normally have my prompt set with the following command:

% set prompt="%n@%m:%~ %% "

This displays my username, then an ‘@’ (at) symbol, followed by the hostname of the machine I’m logged into (in this case “cent1”), then a single ‘:’ (colon) before printing the directory I’m currently in, it finishes with a space followed by the a % symbol and another space. After this is where I’ll type my commands.

The reason I do this is because I’ve got several accounts on multiple machines, so it helps to know what machine I’m logged into (the hostname) and what username I’m running as (my username). If the only Unix account you use is the central Unix servers its reasonable to use something like:

% set prompt="%~ %% "

Which will give you a prompt of your current directory followed by a % symbol to let you easily see where the prompt ends and your typing starts.

If you want to be more adventurous in your prompt usage you could include something like:

% set prompt="[%? %t]%~ %% "

Which would give you the return code, followed by the current time both enclosed inside square brackets, then the current directory (and again the % symbol to show end of the prompt). This gives you more information but a rather cluttered first line.

To unclutter it you could try something like this:

% set prompt="<%n@%m:%l %T> %~ \n%? %% "

That lot is fairly simple if taken from left to right, first a < symbol just because, then the username, an ‘@’ (at), the hostname, a ‘:’ (colon) then the TTY your terminal is connected to, followed by the time in 24 hour format and another > symbol to show the end of that information (the two ‘<’ and ‘>’ symbols are purely cosmetic and could be anything you want, or even left out). This is then followed by your path. After this you’ll note the ‘\n’ sequence, this gives you a new-line, so now your prompt is split over two lines, the new line contains the return code of the previous command followed by a single % (percent) symbol for the end of the prompt.

While prompts themselves aren’t necessary for you to use the Unix systems they can give you a lot of information that saves time in the long run, as you don’t have to type “pwd” a lot to remember where you are, the best way to find a prompt you like is just to spend a few minutes playing about with the examples here and the information in “man tcsh”.

6.5.1  Using the output of other commands in your prompt

Sometimes you’ll want different information than is offered by the escapes above in your prompt. For situations like this you can actually embed the contents of another command in your prompt. This uses the system of encasing commands inside “backticks” (see section 10.3). A simple example would be a modified version of one of the prompts already mentioned. The following prompt will display user@machine:n:directory. Where n is the number of files in the current directory, which is listed as directory. To do this just type:

% set prompt="%n@%h:`ls -l | grep -c '^-'`:%~ % " 

While this may look fairly intimidating its actually not that hard to decode. It includes the %n, %h and %~ escape sequences which you should already be familiar with. Between the %h and %~ escapes you should notice a series of commands enclosed between two backtick characters (which should be available by pressing the key immediately above your tab key, and to the left of the 1 key). What this means is that before printing out the shell tcsh will run these commands.

The commands that are listed are: ls -l | grep -c '^-', sections 4.2.2, 10.1 and 11.1.3 will help you to understand how this command works, in short it runs ls with the -l flag. This lists the long details of all the files in the directory, which of course is one file per line. grep then searches for the pattern '^-' which means look at the start of the line (the ^ character) for a dash. grep also has the -c flag which means “output a count of matching lines, not the lines themselves”.

So an overview of this command is that it prints out all the details, then searches for each line representing a file, and prints out the count of those lines. In other words it counts the files in the current directory (again see the referenced sections above for more information).

6.6  What happens when you log in

You may have noticed by now that a lot of the customisations given (environment variables, prompts etc) don’t stick between sessions. In order to make these changes permanent you’ll need to understand a little about what happens when you log into a Unix system.

Logging in using the C-shell (which “tcsh” is a version of) mainly centres around two configuration files (see section 4.1). These are called “~/.login” and “~/.cshrc” and each contains slightly different things.

The .cshrc file is run first, it should contain all your specific commands that affect the shell itself. Your prompt should be set in here, as well any any other options you want to set (see “man tcsh”). Lastly this file should contain any aliases (see section 6.9.1) you want to set.

.login should contain all the setting of your environment variables, so all the lines running setenv on your $TERM, $VISUAL and $UAEDITOR variables for example. It can also contain any commands you want run whenever you login at the end, for example lines to do with home grown access (see section 13.1) or commands like running the “fortune” program (see section 13.8).

There is no real format for both of those files, they should simply contain the commands you want to run, each on a separate line. If any line has a ‘#’ (hash) symbol in it, everything after the hash will be ignored, and these lines are used for comments so you can remember exactly what and why each real command is in there.

6.7  What happens when you log out

When you type “exit” at your prompt, or if using tcsh simply hit ^D then you will be “logged out” from your shell, disconnecting you from the Unix systems.

Before this happens then the file called “~/.logout” is checked, and any commands listed in here are executed. This means that you could run a program to backup a couple of files when you logged out, or print status information about your session.

An example of this is the following one-liner, which if added to your ~/.logout file will print a nice message before you disconnect:

echo "Goodbye" `grep $USER /etc/passwd | -F: '{print $5}'` "you were logged in from" `who am i | awk '{print $6}' | tr -d '()'` 

Here echo will run, echoing all its arguments, some of which are strings (such as "Goodbye") and the sections in ` (backticks) will execute commands. See sections 10, 10.3 and 11 for more information on how this works.

6.8  running programs

So now you understand about shells, terminals and prompts you might be wondering quite what happens when you type a command and press return.

Assuming that you don’t give an absolute path to a program your shell has only the relative path to work off, and for this it uses the $PATH environment variable.

The default $PATH for shells on cent1 looks like:
“/usr/local/bin:/usr/bin:.:/usr/ccs/bin:/usr/openwin/bin:/usr/dt/bin”

So given the command “ls”, for example, your shell will look in /usr/local/bin, then look in /usr/bin, at which point it will find it. If it hadn’t it will progress to look in ‘.’ (the current directory) and so on.

This means controlling your path variable is a good idea, a good way of setting up the path to include “~/bin” (for any scripts of personal programs you have installed) is covered in section 6.3.2.

6.8.1  Working out where programs are

Since the path has now been documented you might want to see where these programs are that you’ve been running, or even just quickly check that a program is available without using “find” to trawl through the whole hard disk. To do this there is a function built into your shell called “which”, which is used to find a program. For example:

% which ls

Will simply return the path to the “ls” program (usually “/usr/bin/ls”). This can be done for any program, and is quick to run, making it a fast way to find out if a favourite program is available, and also to see if that program is part of homegrown or not (see section 13.1).

6.9  useful things your shell can do:

6.9.1  alias

Now that you’ve got a shell set up with nice variables and prompts to your tastes, and you’re used to regular tasks like editing text, you may find yourself becoming more familiar with commands. Sooner or later you will find a set of options you tend to type each and every time you run a command (“ls -F” for example). To make this easier you can create aliases in your shell, these allow you to run a long and complex command with a few key strokes. For example:

% alias ls "ls -F"

The above command will set up an alias for the string “ls”, and every time that’s typed the shell will execute “ls -F” instead of /bin/ls. Really aliases aren’t much more complex than that ever, other common ones I use are:

% alias ll "ls -lF"

Which means I can see the “long ls” and thus all the permissions of files with “ll” or “ll filename”.

6.9.2  Running multiple programs one after the other

Sometimes you’ll want to run a series of programs one after the other, there are several ways to do this. The easiest is to use a semi-colon.

% first ; second 

This will run the program “first” followed by the program “second”. This is mainly used to run a series of programs in sequence. For example:

% reset ; clear ; source ~/.cshrc ; source ~/.login

This will take your shell and terminal back to the state it was in when you first logged in. First it will reset the terminal, then clear the output of that away, then run .cshrc and .login, which will reset all your environment variables and other associated settings.

A better way of doing this is the use of the && (ampersand, ampersand) construct. This is used to conditionally link commands together. To return to our example:

% reset && clear && source ~/.cshrc && source ~/.login

In this case it will do exactly the same thing, reset the terminal, clear it and source the two configuration files. However because these are linked with && instead of ‘;’ symbols the flow there is an important change. If any of the commands fails (for example reset for some reason fails to work) then the shell will stop executing commands right there. This is good as it means later commands which rely on earlier ones won’t fail, and also it allows you to easily review the error messages from the failed command without having to go digging through the output on your terminal.

6.9.3  clear and redrawing

There is a program (or sometimes its written into the shell, but anyway) called “clear” that does exactly that. If you’ve got a terminal full of the output of other commands and its cluttering your view simply use:

% clear

And your terminal will sudden be returned to just a prompt in the first line.

Similar to this is the ^L key combination. This causes your terminal to redraw itself. If there aren’t any programs running it will function exactly like clear, however most programs (mutt, vim etc) will also acknowledge ^L and will redraw themselves on your screen. So if you are running a full-screen program and it’s display becomes corrupted just press ^L (control and ‘l’).

6.9.4  reset

There are special non-printable characters (i.e. ones you can’t type) that can be sent to a terminal to make it behave differently, display colours, move the cursor backwards and so forth and various programs (editors, mailers, anything that takes over the whole terminal basically) use these to do various effects.

Sometimes if one of these programs fails and quits suddenly, or doesn’t reset the terminal properly it will act funny after its run. Perhaps the cursor keys will stop working, perhaps all the text will have a strange background colour, that kind of thing. To deal with this there is a command that puts your terminal back to its default state:

% reset

It will cause your terminal to flicker a little then output a line telling you “Erase is delete.” then a line about “Kill” and a last one about “Interrupt”. Basically it’ll fix about 99% of programs with terminals going wrong.

6.9.5  mesg

There is a command called “mesg” which relates to how your shell interacts with others attempting to contact you. If you use the command:

% mesg -n

All requests for talk or writes to your terminal (see section 12.5) will be automatically denied, making sure you can work in peace and quiet. If you want to switch them back on simply use:

% mesg -y

6.9.6  MOTD

When ever you log into the Unix systems you should find that your terminal contains a lot of text, this is the Message Of The Day (MOTD) which contains important information about problems with the system and reminders of maintenance and anything else the Admins think you should know.

However, if you don’t want to see this information then you can simply execute the following command:

% touch ~/.hushlogin 

This will create an empty file called “.hushlogin” in your home directory, if this file is there then your shell will not print the MOTD when you log in. However be aware that this means you might miss out on important information. To read the MOTD at other times simply use the command:

% message

Which will let you see the message of the day with less. If you want to start seeing the MOTD when you log in again use the command:

% rm ~/.hushlogin

6.10  Gotchas

There are a number of interesting features of Unix terminals that are worth knowing about in case you ever see them. Most of them exist for historical reasons that never went away, and sometimes they can be useful, sometimes annoying.

6.10.1  Backspaces

Sometimes you’ll find either due to weirdness from the OS manufacturer, or a process feeding your terminal strange control codes your backspace key will stop working correctly. While use of “reset” will normally fix this problem (and its not that common, but it does happen sometimes) if it happens while you are in the middle of something it can be annoying. In those cases its worth knowing about “^H”.

Really old terminals (I think vt100s, I wasn’t using them then so I wouldn’t know for sure, see section 6.4) didn’t include backspace keys. In order to delete a character a combination of keys had to be included and Control and ‘h’ was chosen. So in situations where your backspace key fails you should be able to hold control and press ‘h’ to delete characters until you have the chance to type “reset”.

6.10.2  Changing the size of your terminal

Normally if you just drag the corner of a PuTTY window, or whatever you’re using to log into cent1 to make the window larger your terminal will automatically pick it up and start displaying output at the new size.

Sometimes however this won’t happen, the terminal won’t get the correct resize control codes, or perhaps the program you’re using to log in won’t send them. Anyway, to solve this problem simply type:

% resize

This will force the terminal to re-detect its size. When it runs successfully it will print a couple of lines about “noglob” and in-between those will print out the values of “COLUMNS” and “LINES”, which should be the number of characters wide the terminal is now, and the number of lines of characters high.

6.10.3  Suspend and Resume

Before pagers were common place when people were dealing with large amounts of text being sent to their screen they would use a key combination that suspended the output, the terminal would then sit, storing new output to be displayed. When they had read that screenful they would resume console output, pausing it again if needed.

This functionality has been left in most terminals and should be available to your Unix shell account. Normally you should find your suspend key is set to “^s” and your resume key to “^q” using the notation above.

So if all output stops appearing on your terminal you might have press suspend, try pressing resume and see if that fixes it.

If you want to stop being able to suspend and resume your terminal (for example if you accidentally hit ^s a lot) then you can use the following command to switch off this feature of your terminal:

% stty -ixon

Adding this to your .login will cause it to be run each time you login, thus meaning you will not be able to use the suspend/resume feature.

If you have used stty to switch this off and want to be switch it back on simply type:

% stty ixon

6.10.4  “There are suspended jobs.”

Sometimes when trying to log out you will be greeted by the message “There are suspended jobs.”. The reasons for this are covered in section 7.2 and you should see that section for how to deal with it.


Previous Up Next