ONLamp.com    
 Published on ONLamp.com (http://www.onlamp.com/)
 See this if you're having trouble printing code examples


FreeBSD Basics

Understanding Shell Prompts

09/20/2000

Occasionally, a user will write the FreeBSD questions mailing list asking how to customize his prompt. Inevitably, the responses will include:

While this may seem a brush-off at first glance, it is actually useful advice as prompts are shell specific. Furthermore, if one was to answer with a secret recipe like this:

set prompt = "${e}[1m${USER}@`dirs`${e}[0m% "

the prompt might work, but the original user would have no understanding of "why" this cryptic string of seemingly random characters affected the look of his prompt.

In today's article, we'll look at customizing the prompt for some of the more popular shells. By the end of this article, you should be able to "decode" the above recipe, and create your own custom-combo for your favorite shell.

The following table shows the default prompts for four different shells:

Shell

Executable

Default Prompt

Bourne

sh

$

C

csh

%

tcsh

tcsh

%

Bash

bash

$

Unless you specify otherwise, any user you create will be placed in the Bourne shell. In FreeBSD versions 4.0 and earlier, the root account receives the C shell; this has been changed to the tcsh shell for FreeBSD 4.1. Bash is not installed by default, but is available in the Shells section of the ports collection. Also note that the root user's prompt will be a #, regardless of the shell.

Before we can customize the prompt, we need to know what a shell variable is. Every Unix shell is really a programming language; programming languages use variables to store information. Variables allow you to change or vary their value, hence their name. Your prompt is an example of a shell variable; if you could not change its value, you would be stuck with the defaults of $, %, or #.

Variables can be stored in a file that is read by the shell when you log in or change shells. The following table shows which configuration file(s) can be read by each shell:

Shell Name

Configuration File(s)

Bourne

.profile

C

.cshrc, .login, .logout

tcsh

.tcshrc, .cshrc, .login, .logout

Bash

.bash-profile, .bash_login, .profile, .bashrc, .bashlogout

Since we'll be mucking about with shell variables, let's create a test user account to try out our changes. Become the root user and type:

/stand/sysinstall

and select Configure, User Management, and then User. Input a login ID for the test account and a password you'll remember, and change the Login shell to /bin/csh. When you're finished, leave /stand/sysinstall, exit out of the root account and log in as your test user.

Since you changed the user's shell to the C shell, your prompt should look like this:

%

The user will be in their home directory; to see the configuration files, type:

ls -a

Note that the -a is required, as files that begin with a "." are hidden files. Now type:

more .cshrc

to view the default settings for the C shell. Let's take a closer look at some of these entries:

alias h		history 25
alias j		jobs -l
alias la	ls -a
alias lf	ls -FA
alias ll	ls -lA

After the remarked-out comments section is a set of pre-defined aliases. Aliases are simply abbreviations for commands. Notice the alias called la: it is an abbreviation of ls -a. This means you could have typed la instead of ls -a to see your hidden files. Also note that you can type the letter h to receive your last 25 history entries; this sure beats typing the word history.

You can add your own aliases; they can be useful if you always want to use certain switches with a command. Some good aliases for beginners are:

alias ri	rm -i	#ask before deleting
alias mi	mv -i	#ask before moving over an existing file

Note that when you create an alias, you'll want to choose a name that is not already used by another command, like ri or mi. And be careful with aliases; if you get used to being prompted because of an alias, you may forget this is not the default behavior when you are at another computer or logged in as a different user.

Let's move down to the shell variables:

if ($?prompt) then
	# An interactive shell -- set some stuff up
	set history = 100
	set savehist = 100
	set mail = (/var/mail/$USER)
endif

Note the syntax: set variable = [value]

Value is in brackets -- [] -- as it is optional. This syntax is specific to the C and tcsh shells.

If you wish to change your prompt, the name of the C or tcsh shell variable is prompt. You can set as many values as you want for the prompt variable, as long as they are enclosed within quotation marks. The actual values differ slightly for the C shells and the tcsh shells; if you are using FreeBSD 4.0 or earlier, follow the instructions for the C shell. If you are using FreeBSD 4.1, follow the instructions for the tcsh shell.

Let's try a very simple prompt that works in both the C and tcsh shells. Using your favorite text editor, open up the .cshrc file in your test user's home directory. Add the following line at the very end of the file, just before the endif line.

set prompt = "${USER}% "

Save the file and log out. When you log back in as the test user, your prompt should show your user name, followed by a % followed by a space, and then your cursor. Let's pick apart the string of characters we assigned to the prompt shell variable.

First off, we enclosed the entire value in quotation marks. It is good practice to always do this; it is mandatory if you have any spaces anywhere in your string of characters.

The ${USER} is actually an environment variable. While shell variables are specific to a shell, environment variables are read by all programs (including shells). You can recognize variables as they always start with a $ and are usually enclosed in curly braces -- {}. By convention, environment variables are named in upper case characters, while shell variables are in lower case. If you wish to see your other environment variables, type the following at your command prompt:

env

If you wish to see your shell variables, type:

set

The ${USER} environment variable contains your login name. We can tell the shell prompt variable to read this value when it sets your prompt.

Finally, we put a % after the login name to remind ourselves we are still in the C shell. I like a space between the % and the cursor, so I included one before the last quotation mark.

This prompt is useful as you will always be able to tell at a glance who you are logged in as at a virtual terminal.

I'm a very forgetful person and was forever using the pwd command to figure out where I was in the directory structure. Fortunately, this information can be included in the prompt. To do this in the C shell, replace your set prompt line with the following text:

alias cd 'chdir \!* && set prompt="`dirs`% "'

If you've typed the above without any typos, when you log off and back on, you'll get the regular % prompt. However, after you type cd, your prompt will always tell you what directory you are in, with your home directory shortened to the ~ symbol.

We actually had to do a bit of C programming to get this prompt to work. The C shell understands the ${cwd} or current working directory variable; unfortunately, this will only show what your current directory was when you logged in. We had to create an alias to the cd command if we wanted our prompt to continue to change as we changed directories.

We also had to use the backquote, or ` -- this is on the same key as the ~ symbol. Don't confuse it with this quote -- ', which is on the same key as ". Back quotes are used for command substitution. We used it around the dirs command that tells the C shell to print out the name of the current directory. If you forget the ` quotes, your prompt will literally display the word dirs, instead of the result of the dirs command.

The other new characters we used were &&. This tells your shell that "I want you to do one thing, and when that successfully finishes, I want you to do this next". In summary, we told the shell that when we use the cd command, not only did we want it to change our directory, we also wanted it to set our prompt to show the name of the directory we changed to.

It is much easier to accomplish this same prompt in the tcsh shell, as it has a built-in variable for this purpose. The following string works for the tcsh shell:

set prompt = "%~ % "

The %~ is the built-in variable that shows the current working directory, with a ~ to represent the user's home directory. Again, I used the % to remind myself I was in the C shell (tcsh is really the C shell with extensions to its functionality), and I kept a space between my prompt and the cursor.

I usually like to remember both who I am and where I am, so I set my C shell prompt like this:

alias cd 'chdir \!* && set prompt="${USER}@`dirs`% "'

and my tcsh shell prompt like this:

set prompt = "${USER}@%~ % "

Notice that I've just joined all the desired commands together and enclosed them in quotation marks. I also put an @ as my separator between the username and the current working directory, so my prompt looks like this:

genisis@~ %

We've input some useful information in our prompt, but it would be nice to have its text stand out so we don't confuse it with the other text on the screen. To bold your prompt in the C shell, replace your set prompt text with these lines:

set e="`echo x | tr x \\033`"
alias cd 'chdir \!* && set prompt="${e}[1m${USER}@`dirs`${e}[0m% "'

Since the C shell does not have a built-in variable for bolding text, we had to create our own variable which we called e. Because this is a shell variable, we gave it a name in lowercase; we then used our homemade variable when we set our prompt whenever we did this:

${e}

When we created e, we referred to the ASCII character 033; this character represents the escape character. Every time we referenced ${e}, the shell did the equivalent of pressing the ESC key. Most terminals will interpret ESC[1m to mean "start bolding text." When you want to stop bolding text, ESC[0m tells the terminal to turn off that attribute.

If you prefer, you can underline text by replacing the [1m with [4m. Or you can cause your text to flash by using [5m instead. Don't forget to use [0m to turn off the attribute, or your whole screen will flash, which makes it very hard to work with text!

I usually change root's prompt to be bold and flashing; this can be quite irritating, which reminds me to be root only when I absolutely have to be. To do this, become root and add the following lines to /root/.cshrc. (Note: The line beginning with alias is broken into a second line for the sake of formatting here; it should be entered as one line in your file):

set e="`echo x | tr x \\033`"
alias cd 'chdir \!* && set 
  prompt="${e}[1m${e}[5m${USER}@`dirs`${e}[0m% "'

Note that you can stack the [1m and [5m commands together; just remember to call ${e} before each one so it will press the ESC key for you.

Again, the tcsh shell has built-in variables to accomplish bolding and underlining, so you don't have to define your own variable first. To bold text in the tcsh shell, use this line to set your prompt:

set prompt = "%B${USER}@%~%b% "

In this command, %B starts bolding text and %b stops bolding. To underline text, use %U to start and %u to finish. The tcsh shell has many built-in variables that will let you put the date, time, your hostname, and colors into your prompt.

We've only touched the surface of the possibilities of setting your prompt. You'll want to read the man page for your favorite shell to see what else you can set in that shell's prompt. For example, the C shell's executable is csh, so type:

man csh

to read the man page for the C shell.

The first thing you'll notice about a shell's man page is that it is very long and contains a lot of advanced programming stuff you've probably never heard of. Fortunately, man pages have a search utility; the trick is to try to think of a word that is unique enough to zero in on what you're looking for. To do a search while in a man page, type:

/what_you're_looking_for

For example, you could try:

/shell variables

which will bring your cursor to the next line that contains the words "shell variables". If you still aren't where you want to be, type / and press Enter to go to the next occurrence of your search string.

If you have a favorite shell prompt you would like to share, or an URL that contains some useful shell prompts, post them to the BSD Support Forum on Daemon News and we'll compile a list of readers favorites.

A better search would be something more unique like:

/bold

This would bring you to the %B built-in variable if you were in the tcsh man page. Even if this wasn't the variable you were looking for, you would still be in the shell variable section of the man page.

If you're ever in a long man page and happened to make note of a page number, /60 would take you back to page 60.

Once you find an interesting shell variable or value, try it out in a test user account first to see if you like the results. You don't have to log out and back in to test every change. For example:

source .cshrc

will force the C shell to re-read the .cshrc file and apply any changes you've made.

Next week, we'll discuss running jobs with the cron daemon.

Dru Lavigne is a network and systems administrator, IT instructor, author and international speaker. She has over a decade of experience administering and teaching Netware, Microsoft, Cisco, Checkpoint, SCO, Solaris, Linux, and BSD systems. A prolific author, she pens the popular FreeBSD Basics column for O'Reilly and is author of BSD Hacks and The Best of FreeBSD Basics.


Read more FreeBSD Basics columns.

Return to the BSD DevCenter.

 

Copyright © 2009 O'Reilly Media, Inc.