Fancy Linux command prompt

Let’s face it, if you are going to spend a deal of time at the command prompt, you want to to look good right? After all we have colour terminals now and everything.

The standard Debian command prompt is coloured (unless you are root) and whilst it looks OK, it is a bit… well… boring. I also don’t like the way it gets subsumed in the mass of text, and can be sometimes difficult to look back to the previous commands output.

If you’ve never really played with prompt before, it is configured in the shell variable (which is different to environment variable) that is called PS1. You can easily see what it is set to by just displaying the variable.

cs@www:~$ echo $PS1
${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$
cs@www:~$

Changes to PS1 take place immediatly – try setting the prompt like this.

cs@www:~$ export PS1="Prompt->"
Prompt->pwd
/home/cs
Prompt->

The original setting for the prompt is stored in a hidden bash configuration file that will be in your home directory, known as .bashrc – to see hidden files use the ls -la command and modifiers to list them
To get the prompt back you can just source the file again which will replay it and restore the prompt.

Prompt->ls -la
total 36
drwxr-xr-x 5 cs   cs   4096 Jan 12 17:13 .
drwxr-xr-x 3 root root 4096 Jan 10 02:05 ..
-rw------- 1 cs   cs    191 Jan 14 03:23 .bash_history
-rw-r--r-- 1 cs   cs    220 Jan 10 02:05 .bash_logout
-rw-r--r-- 1 cs   cs   3930 Jan 12 14:07 .bashrc
drwx------ 3 cs   cs   4096 Jan 12 17:13 .config
drwxr-xr-x 3 cs   cs   4096 Jan 12 14:06 .local
-rw-r--r-- 1 cs   cs    807 Jan 10 02:05 .profile
drwx------ 2 cs   cs   4096 Jan 12 13:55 .ssh
Prompt->source ./bashrc
cs@www:~$ 

It’s also possible to add dynamic information like the current user, date and time, and your current directory into the prompt… by adding escape characters you can instruct the prompt to build a custom string for you… for example the \u sequence adds the username and the \t adds the time…

cs@www:~$ export PS1='\u \t ~#'
cs 18:25:57 ~#pwd
/home/cs
cs 18:26:01 ~#

More complex escape sequences allow for colours to be changed, and special characters… These are easily seen in a prompt with the \e construct, followed by a number. A comprehensive list of them can be found here.

https://ss64.com/bash/syntax-prompt.html

Using escape sequences, you can build up colour changes, and special characters and split the prompt across multiple lines. The prompt that I have set on my of my servers also has a little bit of code in that queries the return code from the last command by means of an if statement, and then sets a character to show you if the last prompt succeeded or failed. It also shows the hostname and username, and the current directory on the prompt. The host and username is especially useful when working on multiple systems at the same time.

You can see that when I miss the leading period from the .bashrc file the shell errors, and the return code shows a cross. Successful commands with a return code of zero cause the green tick to be displayed.

The code to do this is not that long, but it is more than a line. You should try setting the command prompt with this all entered on one line with some judicious cut and pasting…

cs@www:~$ export PS1='\[\e]0;\u@\h: \w\a\]\n\[\033[0;37m\]\342\224\214\342\224\200$(if [[ $? == 0 ]]; then echo "[\[\033[0;32m\]\[\033[01;32m\]\342\234\223\[\033[0;37m\]]\342\224\200"; else echo "[\[\033[0;32m\]\[\033[01;31m\]\342\234\227\[\033[0;37m\]]\342\224\200"; fi)[\[\033[0;33m\]\u\[\033[0;37m\]@\[\033[0;96m\]\h\[\033[0;37m\]]\342\224\200[\[\033[0;32m\]\w\[\033[0;37m\]]\n\[\033[0;37m\]\342\224\224\342\224\200'


┌─[✓]─[cs@www]─[~]
└─ 

Remember if it goes horribly wrong, the way back is just to enter source .bashrc assuming you are in your home directory.

Now, getting more fancy, how about a nice bold colour for the user, to remind you if you are running as root…? All you need to is add in another IF statement to check. The general format of this goes like this…

 $(if [[ <condition> ]]; then <do something>; else <do something else>; fi) 

You start the code block with a $ so it is actually executed as code, and wrap the whole thing in brackets.

The colour sequences are escaped with a \033 then the colour sequence, so if we test $USER to see if it is root, we can then write out the opening [ which appears on screen, followed by the \033[0;30m for a dark grey text, and follow up with \033[41m to turn the background bright red. After we print up the username with the \u we can then revert back to regular colours with the sequence \033[0;37m\033[40m
If the user is not root, we print the original sequence instead to display a yellow on black username.

The full command reads as…

export PS1='\[\e]0;\u@\h: \w\a\]\n\[\033[0;37m\]\342\224\214\342\224\200$(if [[ $? == 0 ]]; then echo "[\[\033[0;32m\]\[\033[01;32m\]\342\234\223\[\033[0;37m\]]\342\224\200"; else echo "[\[\033[0;32m\]\[\033[01;31m\]\342\234\227\[\033[0;37m\]]\342\224\200"; fi)$(if [[ $USER == "root" ]]; then echo "[\[\033[0;30m\033[41m\]\u\[\033[0;37m\033[40m\]"; else echo "[\[\033[0;33m\]\u\[\033[0;37m\]"; fi)@\[\033[0;96m\]\h\[\033[0;37m\]]\342\224\200[\[\033[0;32m\]\w\[\033[0;37m\]]\n\[\033[0;37m\]\342\224\224\342\224\200'

It gives a useful warning that you are logged in as root, and therefore need be careful….

The above prompt has been knocking around in my notes for many years, although the idea is not mine. I found it as part of a somewhat esoteric and long gone linux distribution many years ago and tweaked the output a little to suit my tastes more. If anyone can remind me where this did come from, please let me know.

Leave a Reply

Your email address will not be published. Required fields are marked *