Customizing the command prompt is a fairly common modification, but doing so often requires arcane knowledge of shell variables and xterm color strings. My aim here is to list the most common options and show how they might be used.
This discussion assumes one is logging into an account using the bash shell, however korn shell (ksh) and posix shell (sh) should work roughly the same.
The command prompt is defined by the $PS1 system environment variable. By default, it can simply be assigned a fixed string, typically '$ ' for regular users and '# ' for the root user.
However, if you spend any amount of time navigating around a Unix or Linux from the command line, you can customize your command prompt, turning it into a Command Center of useful information.
Before we start, let's talk about the best place to make our modification to $PS1. That would be the shell environment file. For bash, this is $HOME/.bashrc ($HOME/.kshrc for ksh). You would normally not want to make this modification in your .bash_profile, because this script only runs once per login or subshell invocation. If you have active variables in your $PS1 string, they must be in your .bashrc file if they need to be updated each time the command prompt is displayed.
First, how about adding the current working directory to the command line prompt? That way, we can see what directly we are in without having to constantly type 'pwd'. To do this we use the \w token, which bash interprets as the current working directory.
EXAMPLE 1: Embed the current working directory in the prompt:
PS1='\w $ '
Here's some example output:
~ $ cd /usr/bin
/usr/bin $
You can check 'man bash' for the full list. It is listed under the 'PROMPTING' section.
Here is the list for bash 4.2.25:
\a an ASCII bell character (07)
\d the date in "Weekday Month Date" format (e.g., "Tue May 26")
\D{format} the format is passed to strftime(3) and the result is inserted into the prompt string; an empty format results in a locale-specific time representation. The braces are required
\e an ASCII escape character (033)
\h the hostname up to the first `.'
\H the hostname
\j the number of jobs currently managed by the shell
\l the basename of the shell's terminal device name
\n newline
\r carriage return
\s the name of the shell, the basename of $0 (the portion following the final slash)
\t the current time in 24-hour HH:MM:SS format
\T the current time in 12-hour HH:MM:SS format
\@ the current time in 12-hour am/pm format
\A the current time in 24-hour HH:MM format
\u the username of the current user
\v the version of bash (e.g., 2.00)
\V the release of bash, version + patch level (e.g., 2.00.0)
\w the current working directory, with $HOME abbreviated with a tilde (uses the value of the PROMPT_DIRTRIM variable)
\W the basename of the current working directory, with $HOME abbreviated with a tilde
\! the history number of this command
\# the command number of this command
\$ if the effective UID is 0, a #, otherwise a $
\nnn the character corresponding to the octal number nnn
\\ a backslash
\[ begin a sequence of non-printing characters, which could be used to embed a terminal control sequence into the prompt
\] end a sequence of non-printing characters
It is also possible to embed other environment variables or even the result of shell function calls in the $PS1 prompt.
EXAMPLE 2: Embed username, hostname, a customized timestamp, and the current path in the $PS1 prompt:
d ()
{
echo `date +%H%M%S`
}
PS1='\u@\h: $(d) \w $ '
Example output:
pat@mysystem: 124644 /usr/bin $
If you would like a two-line prompt, just use \n to represent the line break.
EXAMPLE 3:
PS1='\u@\h: $(d) \w\n$ '
pat@mysystem: 125139 /usr/bin
$
Adding color to the prompt:
Embedding colors requires adding an escape character and an ANSI color token to the prompt for each color change. Don't forget to change the color back to neutral once you've completed the prompt.
The escape character is encoded as '\e'.
The color change exit command is '\e[0m'.
There are two sets of ANSI colors. A simple 8 color list, and a combo map of 16 basic colors, a 24 level greyscale ramp, and a full 6x6x6 color cube. This is known as "ANSI TrueColor".
Here is the simple 8 color list:
'\e[0;30m' Black
'\e[0;31m' Red
'\e[0;32m' Green
'\e[0;33m' Yellow
'\e[0;34m' Blue
'\e[0;35m' Purple
'\e[0;36m' Cyan
'\e[0;37m' White
EXAMPLE 4: Add primary colors to a multi-component bash shell prompt:
PS1='\e[;0;32m\u@\h:\e[;0;34m$(d) \e[0;33m\w\e[0m\n$ '
pat@mysystem:130100 /usr/bin
$
ANSI TrueColor support
To use TrueColor in your command prompt, you need to know the ANSI escape codes for the particular color you would like to use. There are 16 basic colors, 24 grayscale colors and 216 color cube colors. An easy way to do this would be to run the following perl script in your terminal shell to see all the colors and their associated ANSI escape sequences. You can then embed the colors you want in the same way as shown earlier.
$ cat xterm_256c
#!/usr/bin/env perl
# Display ANSI TrueColor escape sequences and color samples:
# colors 16-231 are a 6x6x6 color cube
for ($red = 0; $red < 6; $red++)
{
for ($green = 0; $green < 6; $green++)
{
for ($blue = 0; $blue < 6; $blue++)
{
$color = 16 + ($red * 36) + ($green * 6) + $blue;
printf ("esc[48;5;%dm: \x1b[38;5;%dmcolor\x1b[38;5;0m\x1b[48;5;%dmcolor\x1b[0m rgb: %2.2x/%2.2x/%2.2x\n",
$color, $color, $color,
$red * 51, $green * 51, $blue * 51);
}
print ("\n");
}
print ("\n");
}
# colors 232-255 are a grayscale ramp, intentionally leaving out
# black and white
for ($gray = 0; $gray < 24; $gray++)
{
$level = ($gray * 10) + 8;
printf("\x1b]4;%d;rgb:%2.2x/%2.2x/%2.2x\x1b\\",
232 + $gray, $level, $level, $level);
}
# display the colors
# first the system ones:
print "System colors:\n";
for ($color = 0; $color < 8; $color++)
{
print "\x1b[48;5;${color}m ";
}
print "\x1b[0m\n";
for ($color = 8; $color < 16; $color++)
{
print "\x1b[48;5;${color}m ";
}
print "\x1b[0m\n\n";
# now the color cube
print "Color cube, 6x6x6:\n";
for ($green = 0; $green < 6; $green++)
{
for ($red = 0; $red < 6; $red++)
{
for ($blue = 0; $blue < 6; $blue++)
{
$color = 16 + ($red * 36) + ($green * 6) + $blue;
print "\x1b[48;5;${color}m ";
}
print "\x1b[0m ";
}
print "\n";
}
print "\n";
# now the grayscale ramp
print "Grayscale ramp:\n";
for ($color = 232; $color < 256; $color++)
{
print "\x1b[48;5;${color}m ";
}
print "\x1b[0m\n";
