datamaskinen

Thomas Frössman's blog on programming, technology, tools, or something like that.

My Bash Prompt

| Comments

UPDATE: I have changed my prompt again, read my bash prompt revisited

Introduction

This is an short but detailed description of a bash prompt. I’m happy with it and haven’t changed it much for a long time. The main focus is to highlight important information and conserve display space by keeping the prompt line as short as possible without sacrificing too much information.

Basic prompt functions:

bash prompt screenshot 1

Format:

TIME USER@HOSTNAME CURRENT-DIRECTORY $

Time

If more than one terminal is open at one time it can be useful to see when or in wich order commands have been executed. The time format is 4 digits (24 hour clock). To conserve space the usual colon infix (:) is omitted.

Username

The name of the currently logged in user. A maximum of 3 characters are displayed.

Hostname

The system hostname. A maximum of 4 characters are displayed.

Current directory

The current working directory. The full path is shown until a 15 characters limit has been reached, then only the initial letter of each directory leading up the the last one is displayed.

Hostnames, SSH and SSH key indicators:

bash prompt screenshot 2

Format:

SSH-KEY-INDICATOR TIME USER@HOST SSH-INDICATOR CURRENT-DIRECTORY $

Key indicator

The SSH key indicator K is shown at the leftmost position of the prompt when the SSH key is detected as loaded by an SSH agent. The key to be identified is chosen by setting an environment variable named SSH_KEY_FINGERPRINT. This can be done just before the prompt code in ~/.bashrc

1
2
3
if [ -n "$SSH_CLIENT" ]; then
  SSH_KEY_FINGERPRINT="00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00"
  export SSH_KEY_FINGERPRINT

Hostname (again)

As seen in the above picture, different host names are automatically given a color to distinguish systems from each other a little bit more.

SSH indicator

The ssh indicator just displays SSH in a high color contrast towards the middle of the prompt line so that it is clear that you probably are on a remote system. This is a saftey feature.

Git repository meta data

bash prompt screenshot 3

Whats going on here?

The git git section of the prompt will show you things like branch name, if there are unstaged or uncommitted changes, if there are mergeable changes fetched or if all commits are pushed.

These features are straight from git’s bash integration which probably are located in /etc/bash_completion.d/git

The actual prompt code

To use this prompt, paste the following into ~/.bashrc or source it from a script:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# Show indication that a certain SSH key is loaded
function __prompt_ssh_agent {
    if [ ! "z" == "z${SSH_KEY_FINGERPRINT}"  ]; then
       keys=`ssh-add -l  2> /dev/null | cut -d ' ' -f 2`
       for k in ${keys}; do
            [ "z$k" == "z${SSH_KEY_FINGERPRINT}" ] && echo -n "K "
       done
    fi
}

# Show user name
function __prompt_username {
    echo -n "$(whoami | cut -c1-3)"
}

# Show host name
function __prompt_hostname {
  echo -n "\[\033[1;$((31 + $(hostname | cksum | cut -c1-3) % 6))m\]\$(hostname | cut -c1-4)"
}

# Show an message if under an SSH session
function __prompt_ssh {
    if [ -n "$SSH_CLIENT" ]; then
        echo -n 'SSH '
    fi
}

# Show GIT status in the prompt
# (This feature is provided by the ubuntu debian git package)
export GIT_PS1_SHOWDIRTYSTATE="yes"
export GIT_PS1_SHOWUPSTREAM="auto"
export GIT_PS1_SHOWUNTRACKEDFILES="yes"

function __prompt_git_branch {
    __git_ps1 "(%s)"
}


# Support function to compactify a path
# copied: http://stackoverflow.com/questions/3497885/code-challenge-bash-prompt-path-shortener
function __dir_chomp {
    local p=${1/#$HOME/\~} b s
    # Remove [ and ] from strings
    # (also, regular expression matching on [ ] below creates infinite recursion.)
    p=${p//[/ }
    p=${p//]/ }
    # Remove multiple spaces, don't need them
    p=${p//  / }
    s=${#p}
    while [[ $p != ${p//\/} ]]&&(($s>$2))
    do
        p=${p#/}
        [[ $p =~ \.?. ]]
        b=$b/${BASH_REMATCH[0]}
        p=${p#*/}
        ((s=${#b}+${#p}))
    done
    echo ${b/\/~/\~}${b+/}$p
}

# Show a compact version of the current directory
function __prompt_pwd {
    echo -n $(__dir_chomp  "$(pwd)" 15)
}


# Prompt output function
function proml {
  # The colors that the prompt uses
  local        BLUE="\[\033[0;34m\]"
  local         RED="\[\033[0;31m\]"
  local   LIGHT_RED="\[\033[1;31m\]"
  local       GREEN="\[\033[0;32m\]"
  local LIGHT_GREEN="\[\033[1;32m\]"
  local       WHITE="\[\033[1;37m\]"
  local  LIGHT_GRAY="\[\033[0;37m\]"

  # Set title in xterm*
  case $TERM in
    xterm*)
    TITLEBAR='\[\033]0;\u@\h:\w\007\]'
    ;;
    *)
    TITLEBAR=""
    ;;
  esac
# And finally, set the prompt 
PS1="${TITLEBAR}\
$LIGHT_GREEN\
\$(__prompt_ssh_agent)\
$RED\
\$(date +%H%M) \
$LIGHT_RED\$(__prompt_username)\
$BLUE@\
$(__prompt_hostname)\
$WHITE \
\$(__prompt_ssh)\
$GREEN\$(__prompt_pwd)\
$RED\$(__prompt_git_branch)\
$GREEN\$ \
$LIGHT_GRAY"
PS2='> '
PS4='+ '
}

# Execute the prompt function
proml

Comments