In this chapter, we will look at a seemingly trivial detail—our shell prompt. This examination will reveal some of the inner workings of the shell and the terminal emulator program.
Like so many things in Linux, the shell prompt is highly configurable, and while we have pretty much taken it for granted, the prompt is a really useful device once we learn how to control it.
Our default prompt looks something like this:
[me@linuxbox ~]$
Notice that it contains our username, our hostname, and our current working directory, but how did it get that way? Very simply, it turns out. The prompt is defined by an environment variable named PS1 (short for “prompt string 1”). We can view the contents of PS1 with the echo command.
[me@linuxbox ~]$ echo $PS1
[u@h W]$
NOTE
Don’t worry if your results are not the same as this example. Every Linux distribution defines the prompt string a little differently, some quite exotically.
From the results, we can see that PS1 contains a few of the characters we see in our prompt such as the brackets, the at-sign, and the dollar sign, but the rest are a mystery. The astute among us will recognize these as backslash-escaped special characters like those we saw in Chapter 7. Table 13-1 provides a partial list of the characters that the bash treats specially in the prompt string.
Table 13-1: Escape Codes Used in Shell Prompts
Sequence |
Value displayed |
a |
ASCII bell. This makes the computer beep when it is encountered. |
d |
Current date in day, month, date format. For example, “Mon May 26.” |
h |
Hostname of the local machine minus the trailing domain name. |
H |
Full hostname. |
j |
Number of jobs running in the current shell session. |
l |
Name of the current terminal device. |
|
A newline character. |
|
A carriage return. |
s |
Name of the shell program. |
|
Current time in 24-hour hours:minutes:seconds format. |
T |
Current time in 12-hour format. |
@ |
Current time in 12-hour AM/PM format. |
A |
Current time in 24-hour hours:minutes format. |
u |
Username of the current user. |
v |
Version number of the shell. |
V |
Version and release numbers of the shell. |
w |
Name of the current working directory. |
W |
Last part of the current working directory name. |
! |
History number of the current command. |
# |
Number of commands entered during this shell session. |
$ |
This displays a $ character unless we have superuser privileges. In that case, it displays a # instead. |
[ |
Signals the start of a series of one or more non-printing characters. This is used to embed non-printing control characters that manipulate the terminal emulator in some way, such as moving the cursor or changing text colors. |
] |
Signals the end of a non-printing character sequence. |
With this list of special characters, we can change the prompt to see the effect. First, we’ll back up the existing prompt string so we can restore it later. To do this, we will copy the existing string into another shell variable that we create ourselves.
[me@linuxbox ~]$ ps1_old="$PS1"
We create a new variable called ps1_old and assign the value of PS1 to it. We can verify that the string has been copied by using the echo command.
[me@linuxbox ~]$ echo $ps1_old
[u@h W]$
We can restore the original prompt at any time during our terminal session by simply reversing the process.
[me@linuxbox ~]$ PS1="$ps1_old"
Now that we are ready to proceed, let’s see what happens if we have an empty prompt string.
[me@linuxbox ~]$ PS1=
If we assign nothing to the prompt string, we get nothing. No prompt string at all! The prompt is still there but displays nothing, just as we asked it to do. Because this is kind of disconcerting to look at, we’ll replace it with a minimal prompt.
PS1="$ "
That’s better. At least now we can see what we are doing. Notice the trailing space within the double quotes. This provides the space between the dollar sign and the cursor when the prompt is displayed.
Let’s add a bell to our prompt.
$ PS1="[a]$ "
Now we should hear a beep each time the prompt is displayed, though some systems disable this “feature.” This could get annoying, but it might be useful if we needed notification when an especially long-running command has been executed. Note that we included the [ and ] sequences. Since the ASCII bell (a) does not “print,” that is, it does not move the cursor, we need to tell bash so it can correctly determine the length of the prompt.
Next, let’s try to make an informative prompt with some hostname and time-of-day information.
$ PS1="A h $ "
17:33 linuxbox $
Adding time-of-day to our prompt will be useful if we need to keep track of when we perform certain tasks. Finally, we’ll make a new prompt that is similar to our original.
17:37 linuxbox $ PS1="<u@h W>$ "
<me@linuxbox ~>$
Try the other sequences listed in Table 13-1 and see whether you can come up with a brilliant new prompt.
Most terminal emulator programs respond to certain non-printing character sequences to control such things as character attributes (such as color, bold text, and the dreaded blinking text) and cursor position. We’ll cover cursor position in a little bit, but first we’ll look at color.
Character color is controlled by sending the terminal emulator an ANSI escape code embedded in the stream of characters to be displayed. The control code does not “print out” on the display; rather, it is interpreted by the terminal as an instruction. As we saw in Table 13-1, the [ and ] sequences are used to encapsulate non-printing characters. An ANSI escape code begins with an octal 033 (the code generated by the ESC key), followed by an optional character attribute, followed by an instruction. For example, the code to set the text color to normal (attribute = 0), black text is as follows: