FREE THOUGHT · FREE SOFTWARE · FREE WORLD

Home  »  Linux  »  Crazy POWERFUL Bash Prompt

by 17 comments

bash power prompt screenshotFrom setting the window title to show the last run command (filtered), saving your history and keeping multi-session history intact, resetting the color/cursor/highlighting of errant color-emitting commands, these 2 prompt examples do more than meet the eye and are extremely fast.

Don't have much time or just don't care? No problem, this is a simple copy and paste... here's one to start (all 1 line, just cut and paste right into the shell, once you've made sure its safe).

PS1="\n\[\e[1;30m\][$$:$PPID - \j:\!\[\e[1;30m\]]\[\e[0;36m\] \T \[\e[1;30m\][\[\e[1;34m\]\u@\H\[\e[1;30m\]:\[\e[0;37m\]${SSH_TTY:-o} \[\e[0;32m\]+${SHLVL}\[\e[1;30m\]] \[\e[1;37m\]\w\[\e[0;37m\] \n\$ "

Basic POWER PROMPT

PROMPT_COMMAND='history -a;echo -en "\033[m\033[38;5;2m"$(( `sed -n "s/MemFree:[\t ]\+\([0-9]\+\) kB/\1/p" /proc/meminfo`/1024))"\033[38;5;22m/"$((`sed -n "s/MemTotal:[\t ]\+\([0-9]\+\) kB/\1/Ip" /proc/meminfo`/1024 ))MB"\t\033[m\033[38;5;55m$(< /proc/loadavg)\033[m"' \
PS1='\[\e[m\n\e[1;30m\][$$:$PPID \j:\!\[\e[1;30m\]]\[\e[0;36m\] \T \d \[\e[1;30m\][\[\e[1;34m\]\u@\H\[\e[1;30m\]:\[\e[0;37m\]${SSH_TTY} \[\e[0;32m\]+${SHLVL}\[\e[1;30m\]] \[\e[1;37m\]\w\[\e[0;37m\] \n($SHLVL:\!)\$ '

Extreme Power Prompt

Updated! 5/25/2010, This is what I use at the moment.. It's the coolest code I've ever seen to do this. I rewrote the above (and below) bash prompts to this format because it is much more robust, and believe it or not its way faster for your machine. Yes the code below is correct, it looks a little weird to export vars from within an exported var statement.. but this is correct. If you just learn this one bit of code, you will gain a lot of shell kung fu, at least I have! Enjoy!

export AA_P="export PVE=\"\\033[m\\033[38;5;2m\"\$(( \`sed -n \"s/MemFree:[\\t ]\\+\\([0-9]\\+\\) kB/\\1/p\" /proc/meminfo\` / 1024 ))\"\\033[38;5;22m/\"\$((\`sed -n \"s/MemTotal:[\\t ]\\+\\([0-9]\\+\\) kB/\\1/p\" /proc/meminfo\`/ 1024 ))MB\"\\t\\033[m\\033[38;5;55m\$(< /proc/loadavg)\\033[m\";echo -en \"\"" \
export PROMPT_COMMAND="history -a;((\$SECONDS % 10==0 ))&&eval \"\$AA_P\";echo -en \"\$PVE\";" \
export PS1="\\[\\e[m\\n\\e[1;30m\\][\$\$:\$PPID \\j:\\!\\[\\e[1;30m\\]]\\[\\e[0;36m\\] \\T \\d \\[\\e[1;30m\\][\\[\\e[1;34m\\]\\u@\\H\\[\\e[1;30m\\]:\\[\\e[0;37m\\]\${SSH_TTY} \\[\\e[0;32m\\]+\${SHLVL}\\[\\e[1;30m\\]] \\[\\e[1;37m\\]\\w\\[\\e[0;37m\\] \\n(\$SHLVL:\\!)\\\$ " \
export PVE="\\033[m\\033[38;5;2m813\\033[38;5;22m/1024MB\\t\\033[m\\033[38;5;55m0.25 0.22 0.18 1/66 26820\\033[m" && eval $AA_P
[24574:16122 0:344] 05:49:07 Wed May 26 [faux@backtrack-askapache:/dev/pts/0 +1] ~
(1:344)$ export AA_P="export PVE=\"\\033[m\\033[38;5;2m\"\$(( \`sed -n \"s/MemFree:[\\t ]\\+\\([0-9]\\+\\) kB/\\1/p\" /proc/meminfo\` / 1024 ))\"\\033[38;5;22m/\"\$((\`sed -n \"s/MemTotal:[\\t ]\\+\\([0-9]\\+\\) kB/\\1/p\" /proc/meminfo\`/ 1024 ))MB\"\\t\\033[m\\033[38;5;55m\$(< /proc/loadavg)\\033[m\";echo -en \"\""
>>> export 'AA_P=export PVE="\033[m\033[38;5;2m"$(( `sed -n "s/MemFree:[\t ]\+\([0-9]\+\) kB/\1/p" /proc/meminfo` / 1024 ))"\033[38;5;22m/"$((`sed -n "s/MemTotal:[\t ]\+\([0-9]\+\) kB/\1/p" /proc/meminfo`/ 1024 ))MB"\t\033[m\033[38;5;55m$(< /proc/loadavg)\033[m";echo -en ""'
>>> AA_P='export PVE="\033[m\033[38;5;2m"$(( `sed -n "s/MemFree:[\t ]\+\([0-9]\+\) kB/\1/p" /proc/meminfo` / 1024 ))"\033[38;5;22m/"$((`sed -n "s/MemTotal:[\t ]\+\([0-9]\+\) kB/\1/p" /proc/meminfo`/ 1024 ))MB"\t\033[m\033[38;5;55m$(< /proc/loadavg)\033[m";echo -en ""'
[24574:16122 0:345] 05:49:09 Wed May 26 [faux@backtrack-askapache:/dev/pts/0 +1] ~
(1:345)$ export PROMPT_COMMAND="history -a;((\$SECONDS % 10==0 ))&&eval \"\$AA_P\";echo -en \"\$PVE\";"
>>> export 'PROMPT_COMMAND=history -a;(($SECONDS % 10==0 ))&&eval "$AA_P";echo -en "$PVE";'
>>> PROMPT_COMMAND='history -a;(($SECONDS % 10==0 ))&&eval "$AA_P";echo -en "$PVE";'
>>> history -a
>>> (( 66 % 10==0  ))
>>> echo -en '\033[m\033[38;5;2m813\033[38;5;22m/1024MB\t\033[m\033[38;5;55m0.35 0.24 0.19 1/68 27241\033[m'
813/1024MB      0.35 0.24 0.19 1/68 27241
[24574:16122 0:346] 05:49:09 Wed May 26 [faux@backtrack-askapache:/dev/pts/0 +1] ~
(1:346)$ export PS1="\\[\\e[m\\n\\e[1;30m\\][\$\$:\$PPID \\j:\\!\\[\\e[1;30m\\]]\\[\\e[0;36m\\] \\T \\d \\[\\e[1;30m\\][\\[\\e[1;34m\\]\\u@\\H\\[\\e[1;30m\\]:\\[\\e[0;37m\\]\${SSH_TTY} \\[\\e[0;32m\\]+\${SHLVL}\\[\\e[1;30m\\]] \\[\\e[1;37m\\]\\w\\[\\e[0;37m\\] \\n(\$SHLVL:\\!)\\\$ "
>>> export 'PS1=\[\e[m\n\e[1;30m\][$$:$PPID \j:\!\[\e[1;30m\]]\[\e[0;36m\] \T \d \[\e[1;30m\][\[\e[1;34m\]\u@\H\[\e[1;30m\]:\[\e[0;37m\]${SSH_TTY} \[\e[0;32m\]+${SHLVL}\[\e[1;30m\]] \[\e[1;37m\]\w\[\e[0;37m\] \n($SHLVL:\!)\$ '
>>> PS1='\[\e[m\n\e[1;30m\][$$:$PPID \j:\!\[\e[1;30m\]]\[\e[0;36m\] \T \d \[\e[1;30m\][\[\e[1;34m\]\u@\H\[\e[1;30m\]:\[\e[0;37m\]${SSH_TTY} \[\e[0;32m\]+${SHLVL}\[\e[1;30m\]] \[\e[1;37m\]\w\[\e[0;37m\] \n($SHLVL:\!)\$ '
>>> history -a
>>> (( 67 % 10==0  ))
>>> echo -en '\033[m\033[38;5;2m813\033[38;5;22m/1024MB\t\033[m\033[38;5;55m0.35 0.24 0.19 1/68 27241\033[m'
813/1024MB      0.35 0.24 0.19 1/68 27241
[24574:16122 0:347] 05:49:10 Wed May 26 [faux@backtrack-askapache:/dev/pts/0 +1] ~
(1:347)$ export PVE="\\033[m\\033[38;5;2m813\\033[38;5;22m/1024MB\\t\\033[m\\033[38;5;55m0.25 0.22 0.18 1/66 26820\\033[m"
>>> export 'PVE=\033[m\033[38;5;2m813\033[38;5;22m/1024MB\t\033[m\033[38;5;55m0.25 0.22 0.18 1/66 26820\033[m'
>>> PVE='\033[m\033[38;5;2m813\033[38;5;22m/1024MB\t\033[m\033[38;5;55m0.25 0.22 0.18 1/66 26820\033[m'
>>> history -a
>>> (( 67 % 10==0  ))
>>> echo -en '\033[m\033[38;5;2m813\033[38;5;22m/1024MB\t\033[m\033[38;5;55m0.25 0.22 0.18 1/66 26820\033[m'

256 Color Prompt Command

NOTE: I have been preparing a 256color terminal article for some time now, as I have tweaked, hacked, read, and experimented with more than I would ever like to admit. So stay tuned, there isn't any tutorial, book, or online howto remotely close to as good as what I'm close to posting...

Super-optimized 256color BASH Prompt

256 color prompt_command and PS1

If you have a 256-color enabled terminal try this..

    export PROMPT_COMMAND='echo -en "\033[m\033[38;5;2m"$(( `sed -n "s/MemFree:[\t ]\+\([0-9]\+\) kB/\1/p" /proc/meminfo`/1024))"\033[38;5;22m/"$((`sed -n "s/MemTotal:[\t ]\+\([0-9]\+\) kB/\1/Ip" /proc/meminfo`/1024 ))MB"\t\033[m\033[38;5;55m$(< /proc/loadavg)\033[m"' \
    export PS1='\[\e[m\n\e[1;30m\][$$:$PPID \j:\!\[\e[1;30m\]]\[\e[0;36m\] \T \d \[\e[1;30m\][\[\e[1;34m\]\u@\H\[\e[1;30m\]:\[\e[0;37m\]${SSH_TTY} \[\e[0;32m\]+${SHLVL}\[\e[1;30m\]] \[\e[1;37m\]\w\[\e[0;37m\] \n($SHLVL:\!)\$ '

Which double-quoted is:

declare -x PROMPT_COMMAND="echo -en \"\\033[m\\033[38;5;2m\"\$(( \`sed -n \"s/MemFree:[\\t ]\\+\\([0-9]\\+\\) kB/\\1/p\" /proc/meminfo\`/1024))\"\\033[38;5;22m/\"\$((\`sed -n \"s/MemTotal:[\\t ]\\+\\([0-9]\\+\\) kB/\\1/Ip\" /proc/meminfo\`/1024 ))MB\"\\t\\033[m\\033[38;5;55m\$(< /proc/loadavg)\\033[m\""
declare -x PS1="\\[\\e[m\\n\\e[1;30m\\][\$\$:\$PPID \\j:\\!\\[\\e[1;30m\\]]\\[\\e[0;36m\\] \\T \\d \\[\\e[1;30m\\][\\[\\e[1;34m\\]\\u@\\H\\[\\e[1;30m\\]:\\[\\e[0;37m\\]\${SSH_TTY} \\[\\e[0;32m\\]+\${SHLVL}\\[\\e[1;30m\\]] \\[\\e[1;37m\\]\\w\\[\\e[0;37m\\] \\n(\$SHLVL:\\!)\\\$ "

For Commandlinefu.com users: Here ya go! toprc

That looks great, and is practicallly totally free in terms of how much cpu/work it makes the shell do for each command. So for slow terminals, or text-terminals like I use, this is great. Other than PS1, there is 1 other variable.. It's called PROMPT_COMMAND and is execed right in front of the PS1. I show 2 ways to utilize this, the goal being to show there is no right way.. fast is fast and money is money. I use a function called aa_pc I threw together that shows me in color how much memory is on my system.. very cool.

PROMPT for Vim and Screen

Here's a screenshot of the code in my vim + screen multiplexed bash 4 environment.. It's placed all the way at the bottom of the file and is the last thing executed by the client processing the script. Also, while it's great to look so good, this is all 100% for efficiency since I use one shell or another every day.

Custom Power Prompt - currently mine

Here's the code I'm using today, that produced this screen-shot -- I am always changing stuff so it's a little more tough to figure out.

  function aa_pc()
  {
        local M=$( free -olm|sed "/Mem/!d; s/Mem:[^0-9]*\([0-9]*\)[^0-9]*\([0-9]*\)[^0-9]*\([0-9]*\).*/ \
        ${GREP_COLOR}\2MB${R}\/\3MB/"; ); echo -e "$M `pwd`"
  }
 
  aa_grep_color(){ export GREP_COLOR=`tput setaf $(aa_random_under 6)`; }
  aa_random_under(){ echo -en $(( $RANDOM % ${1:-$RANDOM} + 1 )); }
  uptime1(){ sed '/.*,  \([0-9]*\) users,  load average: \(.*\)/!d; s//[ \2, \1 users ]/;q';
 
  $SED -n '/i/!Q2' <<< $- && \
  {
        case ${TERM:-dummy} in xterm*|screen*|*color*)echo; ;; *) return; esac;
  }
 
  # hack for being able to source all the functions in this file from a script
  MASTER_RESET=$`echo -e "rs1\nrs2\ninitc\nis2\ncnorm\nrmso\nsgr0" | tput -S`
 
  # only for color-aware (some guessing) terminals, kick everyone else OUT
  case ${TERM:-dummy} in xterm*|screen*|*color*)echo; ;; *) return; esac;
 
  [[ -r /etc/DIR_COLORS ]] && eval `dircolors -b /etc/DIR_COLORS`
 
  # changes the window title in terminals like putty or konsole
  echo -ne "\033]0; ${USER}@${HOSTNAME}  +${SHLVL} @${SSH_TTY/\/dev\/} - `uptime1` \007"
 
  # show title, setup the colors, vars, funcs, settings
  asetup_colors && ascript_title
  export PROMPT_COMMAND='history -a;aa_pc'
  export PS1='\[\033[1;30m\][$$:$PPID - \j:\!\[\033[1;30m\]]\[\033[0;36m\] \T\
  \d \[\033[1;30m\][\[\033[1;34m\]\u@\H\[\033[1;30m\]:\[\033[0;37m\]${SSH_TTY} \
  \[\033[0;32m\]+${SHLVL}\[\033[1;30m\]] \[\033[1;37m\]\w\[\033[0;37m\] \n\$ '

bash power prompt screenshot

I've used many shells over the years and have learned many tweaks and tricks for a powerful prompt. It may look deceptively simple. One cool thing this prompt does is display the command line (filtered) in the putty/konsole/xterm window, so if you have several windows minimized you can easily find the one you are looking for.

There is a lot of good info about the BASH prompt around the net, but it can be complicated for a new user, and as an advanced user you will notice most of the info is very outdated and not very optimized for speed. To get this articles recommended prompt working is devastatingly simple, just export the PROMPT_COMMAND and PS1 variables that are shown below. Most "power prompts" that utilize things like PROMPT_COMMAND do so very haphazardly or very extravagantly.

I've been called a lot of things but not extravagant, and because I use this prompt on many different servers, platforms, and systems I made sure to not make things complicated. To test them just copy and paste the code below into your shell which will export PROMPT_COMMAND and PS1 variables and work right away. So test it out, and if you like it add it to your .bashrc or other startup file (please do a $ man bash).

Bash Power Prompt

bash power prompt PS1
From setting the window title to show the last run command (filtered), saving your history and keeping multi-session history intact, resetting the color/cursor/highlighting of errant color-emitting commands, this prompt does more than meets the eye extremely fast.

Don't have much time? Don't care? You may copy and paste these 2 lines into your shell and that's all there is to it!

export PROMPT_COMMAND='export H1="`history 1|sed -e "s/^[\ 0-9]*//; s/[\d0\d31\d34\d39\d96\d127]*//g; s/\(.\{1,50\}\).*$/\1/g"`";history -a;echo -e "sgr0\ncnorm\nrmso"|tput -S'
export PS1='\n\e[1;30m[\j:\!\e[1;30m]\e[0;36m \T \d \e[1;30m[\e[1;34m\u@\H\e[1;30m:\e[0;37m`tty 2>/dev/null` \e[0;32m+${SHLVL}\e[1;30m] \e[1;37m\w\e[0;37m\[\033]0;[ ${H1}... ] \w - \u@\H +$SHLVL @`tty 2>/dev/null` - [ `uptime` ]\007\]\n\[\]\$ '

PROMPT_COMMAND

This holds commands to be run prior to displaying the prompt. Let's break it down.

PS1 Prompt Example

First this takes the last command executed and filters it using sed to remove the initial history command number, and also to remove any quotes (single or double) and/or backticks. Also, it only saves the first 50 chars, which are then exported as the value of H1, which because it is exported is now globally accessible to the rest of the shell. This is important because we use this variable in PS1 to print the last run command as the title of our putty window (or konsole).

export H1=`history 1 | sed -e 's/^[\ 0-9]*//; s/[\d0\d31\d34\d39\d96\d127]*//g; s/\(.\{1,50\}\).*$/\1/g'`

The next command simply appends your last command to the history file. Usually this is ~/.bash_profile, or whatever $HISTFILE is. This makes sure you never lose history in case of a shell crash or ssh connection terminated.

history -a

Finally there is this golden nugget of shell kung-fu. This outputs 3 terminal escape sequences according to the terminal in use and its capabilities.. so very robust, should work on any shell newer than 1984. By echoing the following 3 term names separated by a newline \n and using tput -S it will output the terminal sequences for all 3. sgr0 resets the colors, cnorm resets the cursor, and rmso resets the background color.

You can view the escape sequences generated by tput with strace, cat -t, etc.. For instance on my shell (xterm-256color via portaputty) the below command generates: \33(B\33[m\33[?12l\33[?25h\33[27m. This is helpful because if you aren't coding for several terminals you can hard code that in your echo's instead of using tput, saving some overhead.

echo -e 'sgr0\ncnorm\nrmso' | tput -S
# For my term this is the same as if I just did
# echo -e "\33(B\33[m\33[?12l\33[?25h\33[27m"

PS1 Detailed

PS1 is the variable that is expanded as your prompt. So if you did a $ unset PS1 then you can still run commands and everything, but your screen will be blank which is confusing to say the least.

The HTOP command in full color to manage mysql

This PS1 shows which SHLVL level the shell is in, which is how many levels deep of shells you are currently at. If you run $ bash -l from a bash shell it will create a new instance of bash as a child of the calling bash, so the SHLVL (shell level) gets incremented by 1. I usually avoid creating subshells by instead executing a new bash with exec which instead of creating a new bash as a child of the current bash, it replaces the current bash process with the new one: $ exec bash -l.

export PS1='\n\e[1;30m[\j:\!\e[1;30m]\e[0;36m \T \d \e[1;30m[\e[1;34m\u@\H\e[1;30m:\e[0;37m`tty 2>/dev/null` \e[0;32m+${SHLVL}\e[1;30m] \e[1;37m\w\e[0;37m\[\033]0;[ ${H1}... ] \w - \u@\H +$SHLVL @`tty 2>/dev/null` - [ `uptime` ]\007\]\n\[\]\$ '
 
# with nocolors
# export PS1='\n[\j:\!] \T \d [\u@\H:`tty 2>/dev/null` +${SHLVL}] \w\[\033]0;[ ${H1}... ] \w - \u@\H +$SHLVL @`tty 2>/dev/null` - [ `uptime` ]\007\]\n\[\]\$ '

TTY

This command is very useful for me because I use multiplexed terminals, about 6 at a time, so it is crucial sometimes to know which tty I am using. Since SSH is the ONLY protocol I ever use for anything, I used to depend on the SSH_TTY variable being set instead of using tty, which as a command has more overhead then just echoing a variable. But I found that when running multiplexing terminals with tmux, screen, etc.. the SSH_TTY variable stays with the initial tty created upon login. Note: 2>/dev/null redirects any errors that running the tty command might issue to the /dev/null device, which is the same thing as a black hole, it goes nowhere so is an efficient way to send data for deletion. Depending on your server and ssh settings you may not even have a tty or it may just appear that you do not. Some web hosting companies do odd things to prevent their users from using tty devices and programs. But if you get a little creative you can always find the current tty.. like $ readlink /proc/self/fd/0 will return the same thing as $ tty.

`tty 2>/dev/null`

Changing Window Title with PS1

This simple bash function changes the title of the window to the passed parameter. The key thing to note is that this works because of the special escapes on either end of the echo'd data.

function set_window_title()
{
  echo -e "\033]0; ${1:-$USER@$HOST - $SHLVL} \007";
}

Additional Info for Hackers

More reading and digging.

Strip Colors for Readability

You can use this command to strip a PS1 of all colors, which shortens the variable dramatically in some cases.

sed 's/\\[eE][[0-9]*;[0-9]*m//g' <<< $PS1
# ie export PS1=$(sed 's/\\[eE][[0-9]*;[0-9]*m//g' <<< $PS1);

Multi-Prompt Switcher Function

This function demonstrates 1 way that you can change your prompts at will. It creates an array named AAPS that you can add as many PS1 values to as you want. Each time the function is run it simply changes the prompt string variable PS1 to the value of the next item in the AAPS array. Once it reaches the last item in AAPS, it resets back to the first AAPS[0] prompt. Just an example to play with, not tested very much.

aa_multi_prompt ()
{
    declare -a AAPS;
    AAPS[0]='\n[\j:\!] \T \d [\u@\H:`tty 2>/dev/null` +${SHLVL}] \w\[\033]0;[ ${H1}... ] \w - \u@\H +$SHLVL @`tty 2>/dev/null` - [ `uptime` ]\007\]\n\[\]\$';
    AAPS[1]='\n[\j:\!] \T \d \n[\u@\H:`tty 2>/dev/null` +${SHLVL}] \w\[\033]0;[ ${H1}... ] \w - \u@\H +$SHLVL @`tty 2>/dev/null` - [ `uptime` ]\007\]\n\[\]\$';
 
    : ${PLVL:=0};
    [[ "${#AAPS[@]}" -lt "$PLVL" || "${#AAPS[@]}" -eq "$PLVL" ]] && PLVL=0;
    export PS1=${AAPS[$PLVL]} && (( PLVL++ )) && export PLVL
}

BASH 4 Multi-Prompt

Here's an example from bash-4, but it works for all bash versions.

prompt ()
{
    case "$1" in
        d)
            PS1='$(dirs) \$ '
        ;;
        n)
            PS1='\$ '
        ;;
        hsw)
            PS1='\h[$SHLVL]: \w \$ '
        ;;
        hw)
            PS1='\h: \w \$ '
        ;;
        sh)
            PS1='[$SHLVL] \h\$ '
        ;;
        sw)
            PS1='[$SHLVL] \w \$ '
        ;;
        uh)
            PS1='\u@\h\$ '
        ;;
        uhsHw)
            PS1='\u@\h[$SHLVL]:\#: \w \$ '
        ;;
        uhsw)
            PS1='\u@\h[$SHLVL]: \w \$ '
        ;;
        uhw)
            PS1='\u@\h: \w \$ '
        ;;
        uw)
            PS1='(\u) \w \$ '
        ;;
        w)
            PS1='\w \$ '
        ;;
    esac
}

Alternative to uptime:

echo "Up for $(( $(sed 's/^\([0-9]*\).*/\1/' /proc/uptime) / (60*60*24) )) days - [`cat /proc/loadavg`]"
# or
echo "Uptime: $(( `sed 's/^\([0-9]*\).*/\1/g' /proc/uptime` / 86400 )) days. Load: $(</proc/loadavg)"

Bash Prompts - More Reading

All Bash Prompt Variables

These are the environment variables provided by BASH (and most shells) and control your prompt string. While all are interesting and good to know about, PROMPT_COMMAND and PS1 are the only ones that directly modify the prompt that is displayed.

PROMPT_COMMAND
If set, the value is executed as a command prior to issuing each primary prompt.
PS1
The value of this parameter is expanded and used as the primary prompt string. The default value is "\s-\v\$ ".
PS2
The value of this parameter is expanded as with PS1 and used as the secondary prompt string. The default is "> ".
PS3
The value of this parameter is used as the prompt for the select command.
PS4
The value of this parameter is expanded as with PS1 and the value is printed before each command bash displays during an execution trace. The first character of PS4 is replicated multiple times, as necessary, to indicate multiple levels of indirection. The default is "+".

Prompt Escape Codes

When executing interactively, bash displays the primary prompt PS1 when it is ready to read a command and the secondary prompt PS2 when it needs more input to complete a command. Bash allows these prompt strings to be customized by inserting a number of backslash-escaped special characters that are decoded as follows:

  • \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
  • \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

The command number and the history number are usually different: the history number of a command is its position in the history list, which may include commands restored from the history file, while the command number is the position in the sequence of commands executed during the current shell session. After the string is decoded, it is expanded via parameter expansion, command substitution, arithmetic expansion, and quote removal, subject to the value of the promptvars shell option, which if set, prompt strings undergo parameter expansion, command substitution, arithmetic expansion, and quote removal after being expanded as described in PROMPTING above. promptvars is enabled by default.

bash power prompt PS1

More Example Prompts

export PS1="\n\e[1;37m[\e[0;32m\u\e[0;35m@\e[0;32m\h\e[1;37m]\e[1;37m[\e[0;31m\w\e[1;37m]\n$ \e[0m"
[user@host][~/bin/tools]
$
export PS1="\n[$?]\e[1;37m[\e[0;32m\u\e[0;35m@\e[0;32m\h\e[1;37m]\e[1;37m[\e[0;31m\w\e[1;37m]($SHLVL:\!)\n\[\033[0m\]\$ "
[0][user@host][~/bin/tools](1:2130)
export PS1='\[\033[1;33m\]\u\[\033[1;37m\]@\[\033[1;32m\]\h\[\033[1;37m\]:\[\033[1;31m\]\w \[\033[1;36m\]\$ \[\033[0m\]'
user@host:~/bin/tools $
export PS1="\e[1;31m[\h]$NC \W > \[\033]0;\${TERM} [\u@\h] \w\]"
[lifesaver] tools >

Benchmarking PROMPT_COMMAND

When figuring out how resource intensive your prompt_command is (if you choose to do that sort of thing), it's nice to do it like this. I ended up using this information from the following test to create the prompt_command used in the first 256-color prompt above.

#!/bin/bash
 
function clean_results()
{
      grep ^real | cut -dm -f2 | sort | uniq -c | sort -n
}
 
for i in {0..500};
do
      time sh -c "expr `sed -nu 's/^MemFree:[\t ]\+\([0-9]\+\) kB/\1/Ip' /proc/meminfo`/1024" &>/dev/nulll;
done 2>&1 | clean_results
 
# print separating line
printf "%$((${COLUMNS:-`tput cols`} - 10))s\n" ' ' | sed -u 's/ /-/g'
 
for i in {0..500};
do
      time sh -c "echo $(( `sed -nu 's/^MemFree:[\t ]\+\([0-9]\+\) kB/\1/Ip' /proc/meminfo`/1024 ))" &>/dev/null;
done 2>&1 | clean_results
 
exit $?

Generates this output, meaning that using expr takes longer.

      1 0.011s
      1 0.014s
      2 0.009s
      2 0.012s
      5 0.008s
     12 0.004s
     47 0.007s
    215 0.005s
    216 0.006s
---------------------------------------------------------------------
      1 0.003s
      2 0.007s
     59 0.006s
    196 0.004s
    243 0.005s

Additional Links

Tags

April 25th, 2014

Comments Welcome

  • deesto

    This is an insanely useful and thorough reference/tutorial/thingy on bash prompts, and as you say, for the impatient or those who don't care, they can literally copy & paste two lines into their terminal (or their bash profile) for an extremely informative prompt. Thanks!

  • Jaysunn

    Hey This is Slick,

    Well done.

    Jaysunn

  • Mr Xhark

    Nice tip ! Thank you

  • AskApache

    Check out this improvement: it's much faster because it only runs on certain seconds. And it's just being evald! Very cool.

            # now this is where things gets really farout, figure out how this works and you'll learn alot
            export AA_P="export PVE="33[m33[38;5;2m"$(( `sed -nu "s/MemFree:[t ]+([0-9]+) kB/1/p" /proc/meminfo` / 1024 ))"33[38;5;22m/"$((`sed -nu "s/MemTotal:[t ]+([0-9]+) kB/1/p" /proc/meminfo`/ 1024 ))MB"t33[m33[38;5;55m$(< /proc/loadavg)33[m";echo -en "$PVE""
            eval "$AA_P" && export PROMPT_COMMAND='history -a;(($SECONDS % 10==0 ))&&eval "$AA_P";echo -en "$PVE";' && eval "$AA_P";
     
            # sets up the prompt
            PS1='[e[mne[1;30m][$$:$PPID j:![e[1;30m]][e[0;36m] T d [e[1;30m][[e[1;34m]u@H[e[1;30m]:[e[0;37m]${SSH_TTY} [e[0;32m]+${SHLVL}[e[1;30m]] [e[1;37m]w[e[0;37m] n($SHLVL:!)$ ';
  • deesto

    thanks for the updated stuff ... but the 'sed -nu' bit breaks in Darwin bash (OS X), and removing the 'u' just hangs the prompt.

  • Maniquí

    Hi. I know you insist on "figure out how this works", but bash code is all gibberish to me.
    On .bash_rc, I've added the "Extreme power prompt" code from above. Now, my prompt looks like this:

    [2873:2872 0:73] 01:50:46 Tue Jun 08 [user@host:/dev/pts/0 +1] ~
    (1:73)$

    Please, could you care to explain some chunks of the output?

    [2873:2872 0:73] <- what are this?

    [user@host:/dev/pts/0 +1] <- what's the +1 here?

    (1:73)$ <- I understand the 73 here is the number of commands I've in the history. What about the 1? And what's the practical use of this numbers?

    Thanks in advance.

  • AskApache

    @deesto

    Ya some versions (mostly older) of sed don't support the -u unbuffered option, I've since removed it since it's a bit overkill anyway and multi-platform robustness is always the goal with bash. It would be helpful if you explained more about what you mean by 'hanging' without the -u option. It's probably related to something other than the u option, a $ set +xv will tell us why (please share what you find).

    Thanks for the feedback bro, I use mac's all the time too (though I greatly prefer nix.)

  • deesto

    @AskApache

    thx! OK, after looking into this, after changing 'sed -nu' to 'sed -n', what's actually happening is that there _is_ no /proc system in Darwin, so the eval command either hangs or throws an error.
    Sucks for us Mac users!

  • tommy

    really awesome and colourful

  • Andrew Grangaard

    I like what you've done here.

    If you're doing that much with your prompt, you may want to consider switching to zsh as your shell.

    If you were in zsh, you could have:

    • *two* awesome prompts, one on the left and one on the right. (The RPROMPT automatically disappears if you type into that area.)
    • And built-ins to show your VCS info (git/svn/... etc).
    • better command-line completion
    • And a flying car.(++)

    ++ flying car may require some assembly.

  • Khashayar

    hi ,

    I'm newbie, i was wonder after each time reboot the prompt will be the same as default one! is there any way to make permanently?
    appreciate your help

    Thanks

  • christopher barry

    very nice and inventive.

    how about adding some themes to the bash-color-tools?

    -C

  • Julien Palard

    For years I used :

    PS1=' '

    A space, only to know that the previous command ended (as while the previous command is running, cursor is at column 0).

    But today I use u@H$ cause I have > 20 servers, I need to know at least the hostname ^-^

  • Julien Palard

    For years I used :

    PS1=' '

    A space, only to know that the previous command ended (as while the previous command is running, cursor is at column 0).

    But today I use u@H$ cause I have > 20 servers, I need to know at least the hostname ^-^

    • AskApache

      Kinda sounds like command.com style, I'll have to try that, but the prompt can and should augment and support shell surfers, especially those who use it interactively all the time..

  • hueydiriritlol

    byeyoto.

My Online Tools


Popular Articles



Hacking and Hackers

The use of "hacker" to mean "security breaker" is a confusion on the part of the mass media. We hackers refuse to recognize that meaning, and continue using the word to mean someone who loves to program, someone who enjoys playful cleverness, or the combination of the two. See my article, On Hacking.
-- Richard M. Stallman



Related Articles

Twitter









[hide]

It's very simple - you read the protocol and write the code. -Bill Joy

Except where otherwise noted, content on this site is licensed under a Creative Commons Attribution 3.0 License, just credit with a link.
This site is not supported or endorsed by The Apache Software Foundation (ASF). All software and documentation produced by The ASF is licensed. "Apache" is a trademark of The ASF. NCSA HTTPd.
UNIX ® is a registered Trademark of The Open Group. POSIX ® is a registered Trademark of The IEEE.

+Askapache | askapache

Site Map | Contact Webmaster | License and Disclaimer | Terms of Service

↑ TOPMain