Customizing The Prompt

Chapter 13

In this section, we'll delve into what might appear insignificant at first glance—the shell prompt. Exploring this will uncover the intricate mechanisms within both the shell and the terminal emulator program.

Within the realm of Linux, the shell prompt offers extensive customization. Despite often overlooking its potential, mastering its control reveals its tremendous utility.

Anatomy Of A Prompt

The standard prompt appears as follows:

[me@linuxmachine ~]$

It showcases our username, hostname, and current directory. But how does it take this shape? Surprisingly, it's quite straightforward. The prompt is set by an environment variable called PS1 (short for "prompt string one"). To view what PS1 contains, you can use the echo command:

[me@linuxmachine ~]$ echo $PS1 
[\u@\h \W]$

Note

If your output doesn't perfectly match the example provided, there's no need for concern. Each Linux distribution crafts its prompt string with its unique touch, resulting in some rather distinctive variations.

The outcomes reveal that PS1 holds some familiar characters present in our prompt—like brackets, the at-sign, and the dollar sign—while the remainder remains somewhat enigmatic. For those observant, these resemble backslash-escaped special characters discussed in Chapter 7. Below is a partial roster of such characters that the shell treats uniquely within the prompt string:

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.

\n

A newline character.

\r

A carriage return.

\s

Name of the shell program.

\t

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 you 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 which 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.

Trying Some Alternative Prompt Designs

Using the special characters listed, we can alter the prompt's appearance. Initially, let's safeguard the current string for future restoration by copying it into a new self-made shell variable:

The new variable ps1_old now holds the value of PS1. To confirm the copy, we can utilize the echo command:

To revert to the original prompt at any point, simply reverse the process:

Once ready, let's experiment. For instance, if we set an empty prompt string:

An empty string yields no prompt display, leaving just a blank screen. To rectify this, let's create a minimal prompt:

This revised prompt includes a trailing space within the quotes, ensuring the cursor's placement after the dollar sign when displayed.

Now, let's introduce a bell sound into our prompt:

This addition prompts a beep with each appearance of the prompt. While potentially bothersome, it can serve as a useful notification for lengthy commands. The \[\] sequences are essential as the ASCII bell (\a) doesn't affect cursor positioning, requiring Bash to accurately determine the prompt's length.

Moving on, let's craft an informative prompt with the current time and hostname:

This modified prompt includes the time-of-day, aiding in tracking task execution timings.

Lastly, let's recreate a prompt resembling the original:

Testing other sequences from the table might lead to creating an innovative prompt design. Feel free to experiment and craft your brilliant new prompt!

Adding Color

Most terminal emulator programs respond to specific non-printing character sequences to manage character attributes such as color, text boldness, and even the infamous blinking effect. Initially, we'll explore color before delving into cursor position.

Terminal Confusion

In the early days, when terminals connected to remote computers, numerous terminal brands existed, each with unique functionalities, keyboards, and interpretations of control data. Unix and similar systems implemented two intricate subsystems, termcap and terminfo, to navigate this diversity in terminal control. Within your terminal emulator settings, you might stumble upon an option for selecting terminal emulation type.

To establish a semblance of uniformity among terminals, the American National Standards Institute (ANSI) devised a standardized collection of character sequences for video terminal control. Those familiar with old DOS systems might recall the ANSI.SYS file, which enabled the interpretation of these codes.

Character color manipulation involves transmitting ANSI escape codes to the terminal emulator, which are embedded within the character stream to be displayed. These control codes don't physically appear on the display; rather, they are interpreted as instructions by the terminal. As detailed in the earlier table, the \[\] sequences serve to encapsulate non-printing characters. An ANSI escape code commences with an octal 033, derived from the escape key, followed by an optional character attribute and an instruction.

For instance, the code to set text color to default (attribute = 0) with black text is:

Below is a table presenting the available text colors, categorized into two groups based on the application of the bold character attribute (1), which creates the effect of "light" colors:

Sequence
Text Color
Sequence
Text Color

\033[0;30m

Black

\033[1;30m

Dark Gray

\033[0;31m

Red

\033[1;31m

Light Red

\033[0;32m

Green

\033[1;32m

Light Green

\033[0;33m

Brown

\033[1;33m

Yellow

\033[0;34m

Blue

\033[1;34m

Light Blue

\033[0;35m

Purple

\033[1;35m

Light Purple

\033[0;36m

Cyan

\033[1;36m

Light Cyan

\033[0;37m

Light Grey

\033[1;37m

White

Let's attempt to create a red prompt. We'll integrate the escape code at the start:

It displays in red, but notice that all subsequently typed text also appears red. To resolve this, we'll append another escape code at the end of the prompt, instructing the terminal emulator to revert to the previous color:

Ah, much better!

Furthermore, the provided codes below can set the text background color. However, note that the background colors don't support the bold attribute.

Sequence
Background Color
Sequence
Background Color

\033[0;40m

Black

\033[0;44m

Blue

\033[0;41m

Red

\033[0;45m

Purple

\033[0;42m

Green

\033[0;46m

Cyan

\033[0;43m

Brown

\033[0;47m

Light Grey

Altering the initial escape code allows us to craft a prompt with a red background.

Try out the color codes and see what you can create!

Note

Besides the normal (0) and bold (1) character attributes, text may also be given underscore (4), blinking (5), and inverse (7) attributes as well. In the interests of good taste, many terminal emulators refuse to honor the blinking attribute, how- ever.

Moving The Cursor

Using escape codes allows for cursor positioning, a technique often employed to display a clock or other information in various screen locations, like an upper corner, each time the prompt appears. Below is a compilation of escape codes used for cursor positioning:

Escape Code
Action

\033[l;cH

Move the cursor to line l and column c

\033[nA

Move the cursor up n lines

\033[nB

Move the cursor down n lines

\033[nC

Move the cursor forward n characters

\033[nD

Move the cursor backward n characters

\033[2J

Clear the screen and move the cursor to the upper left corner (line 0, column 0)

\033[K

Clear from the cursor position to the end of the current line

\033[s

Store the current cursor position

\033[u

Recall the stored cursor position

Employing the provided codes, we'll create a prompt that generates a red bar at the screen's top, showcasing a clock (in yellow text) whenever the prompt appears. The prompt code takes the form of this rather complex-looking string:

Let's take a look at each part of the string to see what it does:

Sequence
Action

\[

Initiates a sequence of non-printing characters. This step enables Bash to accurately determine the visible prompt's size. This calculation is crucial for the precise positioning of the cursor in command line editing features.

\033[s

Save the current cursor position. This action ensures a return to the prompt's original location after drawing the bar and clock at the screen's top. Note that certain terminal emulators might not adhere to this specific code.

\033[0;0H

Move the cursor to the upper left corner, which is line 0, column 0.

\033[0;41m

Set the background color to red.

\033[K

Erase from the current cursor position (top left corner) to the end of the line. As the background color is set to red, this action clears the line to that color, forming our designated bar. It's important to note that clearing to the end of the line doesn't affect the cursor position, which remains at the upper left corner.

\033[1;33m

Set the text color to yellow.

\t

Render the present time. Despite being a "printing" component, it's included in the non-printing segment of the prompt. This ensures that Bash doesn't factor the clock into the actual size calculation of the displayed prompt.

\033[0m

Turn off color. This affects both the text and background.

\033[u

Restore the cursor position saved earlier.

\]

End the non-printing characters sequence.

<\u@\h \W>$

Prompt string.

Saving The Prompt

Clearly, we don't intend to type that lengthy command repeatedly, so let's save our prompt somewhere. We can ensure its permanence by appending it to our .bashrc file. Simply add these two lines to the file:

Summary

Surprisingly, there's a lot more to explore regarding prompts, involving shell functions and scripts beyond what we've covered here. Nonetheless, this serves as a solid introduction. Not everyone will find it necessary to alter the prompt, as the default one usually suffices. Yet, for those of us inclined to experiment, the shell offers countless hours of enjoyable tinkering and exploration.

Last updated