Skip to main content

Bash Profiles

Organizing Bash Settings

The following block contains a list of files related to bash, and their location / use.

           /bin/bash
	The bash executable

/etc/bash.bashrc
	The system-wide bashrc for interactive bash shells, invoked on any login to an interactive shell.

/etc/skel/.bashrc
	Used as a template for new users when initializing a basic .bashrc in their home directory. 

/etc/profile
	The systemwide initialization file, executed for login shells

/etc/bash.bash_logout
	The systemwide login shell cleanup file, executed when a login shell exits

~/.bash_profile
	The personal initialization file, executed for login shells

~/.bashrc
	The individual per-interactive-shell startup file

~/.bash_aliases
	An optional file sourced by .bashrc by default

~/.bash_logout
	The individual login shell cleanup file, executed when a login shell exits
~/.inputrc
                  Individual readline initialization file

I often refer to the bash reference found within the bash-doc package. It's nice to have good documentation local on your system, in case you are working with no internet connection for any reason. For Ubuntu, run sudo apt install bash-doc and navigate to the /usr/share/doc/bash-doc/ directory for a collection of examples and more detailed bash references. To help you explore these files, consider installing the terminal file browser ranger with sudo apt install ranger.

CreatingIf Userit Profiles

Createis a custom.html bashfile, profileopen forit yourin usera withinweb their home directory by modifying ~/.bashrc. The important linesbrowser to customize are seen below -

# Bash prompt settings

if [ "$color_prompt" = yes ]; then
    PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
else
    PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
fi

# Alias / export customizations

# colored GCC warnings and errors
#export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01'

# some more ls aliases
alias ll='ls -alF'
alias la='ls -A'
alias l='ls -CF'

# Add an "alert" alias for long running commands.  Use like so:
#   sleep 10; alert
alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"'

# You may want to put all your additions into a separate file like
# ~/.bash_aliases, instead of adding them here directly.
# See /usr/share/doc/bash-doc/examples in the bash-doc package.
if [ -f ~/.bash_aliases ]; then
    . ~/.bash_aliases
fi1

\[\033[1;31m\]\h\336\220\u\336\220\[\033[0;32m\]\w\[\033[1;31m\]]\@:\340\264\275_\$?\n\337\206\s\[\033[0;32m\]\342\225\274$

# Auto-completion

# enable programmable completion features (you don't need to enable
# this, if it's already enabled in /etc/bash.bashrc and /etc/profile
# sources /etc/bash.bashrc).
if ! shopt -oq posix; then
  if [ -f /usr/share/bash-completion/bash_completion ]; then
    . /usr/share/bash-completion/bash_completion
  elif [ -f /etc/bash_completion ]; then
    . /etc/bash_completion
  fi
fi

Identifying Unicode Symbols for use in .bashrc

Character search engine

If you dont have access to a terminal, you can search up a symbol to get UTF8, see the below character and the corresponding UTF8 format as an example. ഽ = 0xE0 0xB4 0xBD

Hexdump unicode symbol

Most linux systems already have hexdump installed, so we could also run echo ސ | hexdump -C to see the following output -

[kapper@kubuntu-vbox ~]$echo ސ | hexdump -C
00000000  de 90 0a
00000003

From this output, we can see that the UTF8 hexidecimal format of our symbol is \xde\x90\x0a. Using this information, we can test the coloring the character green with the echo statement below.

echo -e '\001\033[1;32m\xde\x90\x0a\033[0m\002'

Unicode.vim

Worth mentioning that if you are using vim, an easy to use plugin that is useful for identifying characters is unicode.vim. See my notes on Unicode vim plugin for more information, or check out the official Unicode vim repository.

Bash Aliases

create a list of aliases within your home directory within a file named .bash_aliases, or feel free to customize the following lines in your local .bashrc

# ~/.bashrc
# Alias / export customizations

# colored GCC warnings and errors
#export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01'

# some more ls aliases
alias ll='ls -alF'
alias la='ls -A'
alias l='ls -CF'

# Add an "alert" alias for long running commands.  Use like so:
#   sleep 10; alert
alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"'

# You may want to put all your additions into a separate file like
# ~/.bash_aliases, instead of adding them here directly.
# See /usr/share/doc/bash-doc/examples in the bash-doc package.

if [ -f ~/.bash_aliases ]; then
    . ~/.bash_aliases
fi

For example, I decided to move most of the default information above to my own .bash_aliases file, so I could edit it all in one place. I make my edits at the top ofbrowse the file with additional custom aliases.easily.

alias gitkapp='git config --global user.name "Shaun Reed" && git config --global user.email "shaunrd0@gmail.com"'


# Default .bashrc aliases stored here

# Alias / export customizations

# colored GCC warnings and errors
#export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01'

# some more ls aliases
alias ll='ls -alF'
alias la='ls -A'
alias l='ls -CF'

# Add an "alert" alias for long running commands.  Use like so:
#   sleep 10; alert
alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"'

The gitkapp alias above is a quick way of telling git who I am when logged in as a new user. Aliases even show up using auto completion -

[user@host ~]$git
git                 git-shell           git-upload-pack     
git-receive-pack    git-upload-archive  gitkapp             
[user@host ~]$gitkapp 

Environment Variables

PS1: environment variable which contains the value of the default prompt. It changes the shell command prompt appearance and environment.

PS2: environment variable which contains the value the prompt used for a command continuation interpretation. You see it when you write a long command in many lines.

PS3: environment variable which contains the value of the prompt for the select operator inside the shell script.

PS4: environment variable which contains the value of the prompt used to show script lines during the execution of a bash script in debug mode.

Bash Prompt

Your bash prompt is whats seen before you type a command -

user@host:~/$ 

This is defined by the PS1 variable within your .bashrc -

# Bash prompt settings

if [ "$color_prompt" = yes ]; then
    PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
else
    PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
fi

There's two settins to configure, the first block includes color, the second does not.

You can change this using any variety of the settings below. After you've got a good export working, paste it into the ~/.bashrc to apply your changes each time you login. If you skip this step and log out of your terminal with an export applied, when you login it will be overwritten by the code above.

Export Examples

Any of the below exports can be pasted directly into the terminal to be tested. Once the terminal is closed, these settings will be lost, so no worries about getting back to default. This is a good way to test what would happen if you changed the PS1 within your .bashrc, without actually doing so.

Below are some examples, each more complicated than the last to show how many options are available. These, of course are still only a few.

export PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\][\u@\h\[\033[00m\] \W\[\033[01;32m\]]\$\[\033[00m\]'
export PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\][\u]\[\033[00m\] \w\[\033[00m\]\n\[\033[01;32m\]\337\206\[\033[00m\]\[\033[10;92m\]\h\[\033[00m\]\[\033[01;32m\]]\W:\$\[\033[00m\] '

No color Parrotsec

export PS1='┌──˨\u@\h─[\w]\n└──╼\$`

Colorized Parrotsec

export PS1="\[\033[0;31m\]\342\224\214\342\224\200\$([[ \$? != 0 ]] && echo \"[\[\033[0;31m\]\342\234\227\[\033[0;37m\]]\342\224\200\")[$(if [[ ${EUID} == 0 ]]; then echo '\[\033[01;31m\]root\[\033[01;33m\]@\[\033[01;96m\]\h'; else echo '\[\033[0;39m\]\u\[\033[01;33m\]@\[\033[01;96m\]\h'; fi)\[\033[0;31m\]]\342\224\200[\[\033[0;32m\]\w\[\033[0;31m\]]\n\[\033[0;31m\]\342\224\224\342\224\200\342\224\200\342\225\274 \[\033[0m\]\[\e[01;33m\]\\$\[\e[0m\]"
Bash Options
$PS1 : Your shell prompt variable
\e[ : Start color scheme.
\033: equivalent to \e as an escape code
x;y : Color pair to use (x;y)
\e[m : Stop color scheme.
\H: Display FQDN hostname.
\@: Display current time in 12-hour am/pm format
\u: Display the current username .
\h: Display the hostname
\w: Print the entire working directory.
\W: Print the base of current working directory.
\$: Display # (indicates root user) if the effective UID is 0, otherwise display a $.

So we can create a simple export like the below, to test these values before adding any color

export PS1='${debian_chroot:+($debian_chroot)}FQDN: \H | Host: \h \w\n\u\W:\$'

More Prompt References

\a The ASCII bell character (you can also type \007)
\d Date in “Sat Sep 04″ format
\e ASCII escape character (you can also type \033)
\h First part of hostname (such as “mybox”)
\H Full hostname (such as “mybox.mydomain.com”)
\j The number of processes you’ve suspended in this shell by hitting ^Z
\l The name of the shell’s terminal device (such as “ttyp4″)
\n Newline
\r Carriage return
\s The name of the shell executable (such as “bash”)
\t Time in 24-hour format (such as “23:59:59″)
\T Time in 12-hour format (such as “11:59:59″)
\@ Time in 12-hour format with am/pm
\u Your username
\v Version of bash (such as 2.04)
\V Bash version, including patchlevel
\w Current working directory (such as “/home/koithara”)
\W The “basename” of the current working directory (such as “koithara”)
\! Current command’s position in the history buffer
\# Command number (this will count up at each prompt, as long as you type something)
\$ If you are not root, inserts a “$”; if you are root, you get a “#”
\xxx Inserts an ASCII character based on three-digit number xxx (replace unused digits with zeros, such as “\007″)
\\ A backslash

\[ This sequence should appear before a sequence of characters that don’t move the cursor (like color escape sequences). This allows bash to calculate word wrapping correctly.
\] Same as \002, This sequence should appear after a sequence of non-printing characters.

\001 can be used directly in place of \[ and is recommended as a more portable option
\002 can be used directly in place of \] and is recommended as a more portable option

To take a closer look, lets break down the default Parrotsec PS1 value, which contains unique colorization, formatting and symbols. Starting with the first and worst example below, we threw some color codes, bash variables (\h,\w, etc), and copied some symbols from google into the below. This is a misuse of escape sequences [ and \], and uses symbols directly in our .bashrc, which isn't allowed.

'\e[\[0;31m\]\hސ\uސ[\e[\[0;32m\]\w\e[\[0;31m\]]\@:ഽ_\$?\n߆\s\e[\[0;32m\]╼$'

Correct escape sequences, misuse of symbols -

'\[\033[1;31m\]\hސ\uސ f\[\033[0;32m\]\w\[\033[1;31m\]]\@:ഽ_\$?\n߆\s\[\033[0;32m\]╼$'

Correct escape sequences and symbols:

'\[\033[1;31m\]\h\336\220\u\336\220\[\033[0;32m\]\w\[\033[1;31m\]]\@:\340\264\275_\$?\n\337\206\s\[\033[0;32m\]\342\225\274$

On some systems, its required to use \001 in place of \[ and \002 in place of \]. Since this method also works on systems that support \[ and \], so this could be a more portable option.

'\001\033[1;31m\002\h\336\220\u\336\220\001\033[0;32m\002\w\001\033[1;31m\002]\@:\340\264\275_\$?\n\337\206\s\001\033[0;32m\002\342\225\274$'

Note that we do not close an escape sequence until we are finished. See the below for examples

# Ok
echo -e '\001\033[1;32m\xde\x90\x0a\033[0m\002'
# Wrong, no need to close `\001` with `\002` until we are finished with the entire sequence
echo -e '\001\033[1;32m\002\001\xde\x90\x0a\002\001\033[0m\002'
Color codes

Using the appropriate bash syntax and following the codes below,
Toss this escape code in to colorize everything green after:
\001[0;32m\002

Black0;30Dark Gray1;30
Blue0;34Light Blue1;34
Green0;32Light Green1;32
Cyan0;36Light Cyan1;36
Red0;31Light Red1;31
Purple0;35Light Purple1;35
Brown0;33Yellow1;33
Light Gray0;37White1;37

System Profile

When a bash profile is not placed in the home directory, the default profile is loaded from /etc/profile. This file simply checks for a local configuration in the user home directory, and if it does not exist it applies default settings. If you would like to edit or specify certain settings for certain users, a ~/.bashrc file canshould be created or reconfigured, depending on your current setup. The page below will show some basic syntax for editing the file, along with some examples. The default bash profile/etc/profile/ can be seen in the code block below.

In short, to set a system-wide variable, such as EDITOR='/usr/bin/vim', simply add the following line to /etc/profile -

    # /etc/profile: system-wide .profile file for the Bourne shell (sh(1))
    # and Bourne compatible shells (bash(1), ksh(1), ash(1), ...).

    # This line sets the system-wide default text editor to vim
    export EDITOR='/usr/bin/vim'
    export VISUAL='/usr/bin/vim'

    if [ "${PS1-}" ]; then
      if [ "${BASH-}" ] && [ "$BASH" != "/bin/sh" ]; then
        # The file bash.bashrc already sets the default PS1.
        # PS1='\h:\w\$ '
        if [ -f /etc/bash.bashrc ]; then
          . /etc/bash.bashrc
        fi
      else
        if [ "`id -u`" -eq 0 ]; then
          PS1='# '
          # This block allows for configuring any user whos id == 0
          # In other words, these settings will be applied to the root user only.
        else
          PS1='$ '
          # These settings will apply in all other cases, system-wide
          # In other words, upon successful login to an authroized user, this block will be executed
        fi
      fi
    fi

    if [ -d /etc/profile.d ]; then
      for i in /etc/profile.d/*.sh; do
        if [ -r $i ]; then
          . $i
        fi
      done
      unset i
    fi

The above /etc/profile configuration will set the default editor to vim, system-wide, regardless of which user is logged in. This includes the root user.

If you want to specify which user, or if you want to handle the root user independent from the rest of the system, take a closer look at the comments I've added in the above configuration file and modify as needed.

If you are trying to change the default text editor for any command ran with sudo, be sure that you pass the -E or --preserve-env argument to sudo when attempting to test these settings. So, if we wanted to preserve our environment setting for the default text editor when running vigr or visudo we would simply run sudo -E vigr or sudo --preserve-env visudo to ensure these settings are referred to when using sudo

Skeleton Configurations

As stated in the first section, the /etc/skel/ directory contains files that are distributed to each new user created on our system. This is useful to know, since we can directly modify these files to provide different default configurations provided when new users are created. This can be a nice way to ensure that all users start with the same aliases, or are shown a similar prompt. We can even specify other defaults here, like providing a default .vimrc to distribute to new users, or setting certain shell options.

Creating User Profiles

Login as your user and create a custom bash profile within their home directory by modifying ~/.bashrc, or /home/username/.bashrc. The important lines to customize are seen below -

Bash prompt

if [ "$color_prompt" = yes ]; then
    PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
else
    PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
fi

Alias / export customizations

# colored GCC warnings and errors
#export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01'

# some more ls aliases
alias ll='ls -alF'
alias la='ls -A'
alias l='ls -CF'

Additional files to source

# You may want to put all your additions into a separate file like
# ~/.bash_aliases, instead of adding them here directly.
# See /usr/share/doc/bash-doc/examples in the bash-doc package.
if [ -f ~/.bash_aliases ]; then
    . ~/.bash_aliases
fi1

Auto-completion

# enable programmable completion features (you don't need to enable
# this for each user, if it's already enabled in /etc/bash.bashrc and /etc/profile
if ! shopt -oq posix; then
  if [ -f /usr/share/bash-completion/bash_completion ]; then
    . /usr/share/bash-completion/bash_completion
  elif [ -f /etc/bash_completion ]; then
    . /etc/bash_completion
  fi
fi

Environment Variables

PS1: Environment variable which contains the value of the default prompt. It changes the shell command prompt appearance.

kapper@kubuntu-vbox $ export PS1='[\u@\h \W]\$'
[kapper@kubuntu-vbox ~]$

PS2: Environment variable which contains the value the prompt used for a command continuation interpretation. You see it when you write a long command in many lines. In most cases, this is set to > , and is seen below after using the \ character to break the command into several lines -

[kapper@kubuntu-vbox ~]$ export PS2='--> '
[kapper@kubuntu-vbox ~]$ cp /some/really/long/system/path/fileOne \
--> fileTwo

PS3: Environment variable which contains the value of the prompt for the select operator inside the shell script.

PS4: Environment variable which contains the value of the prompt used to show script lines during the execution of a bash script in debug mode. This could be used to show the line number at the current point of execution -

# $0 is the current file being executed, $LINENO is the current line number
[kapper@kubuntu-vbox ~]$ export PS4='$0:$LINENO'
[kapper@kubuntu-vbox ~]$ bash -x fix-vbox.sh 
fix-vbox.sh:5grep 'VBoxClient --draganddrop'
fix-vbox.sh:6awk '{print $2}'
fix-vbox.sh:7xargs kill
fix-vbox.sh:8ps aux www

PROMPT_COMMAND: Environment variable which contains command(s) to run before printing the prompt within the terminal.

[kapper@kubuntu-vbox ~]$export PROMPT_COMMAND='echo -n "$(date): " && pwd'
Sun 12 Sep 2021 05:00:55 PM EDT: /home/kapper
[kapper@kubuntu-vbox ~]$ls
 Desktop     Music        Pictures   Videos
 Code        Public     Documents   Downloads
Sun 12 Sep 2021 05:01:02 PM EDT: /home/kapper

Bash Aliases

create a list of aliases within your home directory within a file named .bash_aliases, and add any custom aliases or PATH modifications there. This way when you want to adjust your PATH or aliases, you don't have to dig through all the contents of .bashrc. For example, some of the contents of my ~/.bash_aliases is seen below. This file will automatically be sourced by bash when logging into our user, in addition to the contents of the ~/.bashrc.

# Alias / export customizations
alias gitkapp='git config --global user.name "Shaun Reed" && git config --global user.email "shaunrd0@gmail.com"'

# colored GCC warnings and errors
export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01'

# some more ls aliases
alias ll='ls -alF'
alias la='ls -A'
alias l='ls -CF'

The gitkapp alias above is a quick way of telling git who I am when logged in as a new user. You could imagine having more versions of this alias to switch to different git users quickly. Alternatively, you could use the git config --local ... command within the alias to automate configuring a specific repository for a certain user in a single command without modifying your global git user. Aliases even automatically show up using auto completion -

[user@host ~]$git
git                 git-shell           git-upload-pack     
git-receive-pack    git-upload-archive  gitkapp             
[user@host ~]$gitkapp 

Identifying Unicode Symbols for use in .bashrc

Character search engine

If you dont have access to a terminal, you can search up a symbol to get UTF8, see the below character and the corresponding UTF8 format as an example. ഽ = 0xE0 0xB4 0xBD

To output this symbol in a bash terminal using this hex value, we can test with echo -

echo -e '\xe0\xb4\xbd'

Note that these hexidecimal values are not case sensitive.

Hexdump unicode symbol

Most linux systems already have hexdump installed, so we could also run echo ✓ | hexdump -C to see the following output. Note that the -C option displays character data in hexidecimal ascii format -

[kapper@kubuntu-vbox ~]$echo ✓ | hexdump -C
00000000  e2 9c 93 0a                                       |....|
00000004

From this output, we can see that the UTF8 hexidecimal format of our symbol is e2 9c 93. Using this information, we can test the character with the echo statement below.

echo -e '\xe2\x9c\x93'

This will out our  symbol, colored green. \001\033[1;32m\002 Begins the green color, and \001\033[0m\002 returns to

echo -e '\001\033[1;32m\002\xe2\x9c\x93\001\033[0m\002'

Unicode.vim

Worth mentioning that if you are using vim, an easy to use plugin that is useful for identifying characters is unicode.vim. See my notes on Unicode vim plugin for more information, or check out the official Unicode vim repository.

In any case, when using special characters and symbols in an assignment to PS1, you need to tell bash to interpret these values with a $ before opening your single-quotes, as in export PS1=$'\xe2\x9c\x93'

Bash Prompt

Your bash prompt is seen before you type a command -

user@host:~/$ 

The prompt above, user@host:~/$, is defined by the PS1 variable within your ~/.bashrc where \u is your the username user, and \h is the hostname host in the prompt above. The \w in the prompt is what places our current directory ~/ before the final $ within the prompt -

# Bash prompt settings

if [ "$color_prompt" = yes ]; then
    PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
else
    PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
fi

By default within your .bashrc there's two settings to configure, the first block includes color, the second does not. When first learning about the prompt and all the available options like \u, \h, and \w, it might be easier to look at the second prompt without the escape sequences for adding color. As we will see later, care must be taken to properly escape non-printing characters within your prompt, specifically color codes. That is the meaning of character sequences like \[\033[01;32m\]. Later we will cover the meaning of these symbols and how to properly organize them within your prompt.

You can change this using the variety of settings below. Test your prompts with export PS1='<YOUR_PROMPT_HERE>' and after you've got a good export working, paste it into the ~/.bashrc to apply your changes each time you login. If you skip this step and log out of your terminal with an export applied, when you login it will be overwritten by the code above.

Prompt Options

When setting your bash prompt, we have the following escape sequences available. For example, can be used to place the current username in place of the \u sequence. So the prompt export PS1='\u@\h: will make our prompt username@hostname:

\a The ASCII bell character (you can also type \007)
\d Date in “Sat Sep 04″ format
\e ASCII escape character (you can also type \033 or \x1B)
\h First part of hostname (such as “mybox”)
\H Full hostname (such as “mybox.mydomain.com”)
\j The number of processes you’ve suspended in this shell by hitting ^Z
\l The name of the shell’s terminal device (such as “ttyp4″)
\n Newline
\r Carriage return
\s The name of the shell executable (such as “bash”)
\t Time in 24-hour format (such as “23:59:59″)
\T Time in 12-hour format (such as “11:59:59″)
\@ Time in 12-hour format with am/pm
\u Your username
\v Version of bash (such as 2.04)
\V Bash version, including patchlevel
\w Current working directory (such as “/home/koithara”)
\W The “basename” of the current working directory (such as “koithara”)
\! Current command’s position in the history buffer
\# Command number (this will count up at each prompt, as long as you type something)
\$ If you are not root, inserts a “$”; if you are root, you get a “#”
\xxx Inserts an ASCII character based on three-digit number xxx (replace unused digits with zeros, such as “\007″)
\\ A backslash

\[ This sequence should appear before a sequence of characters that don’t move the cursor (like color escape sequences). This allows bash to calculate word wrapping correctly.
\] Same as \002, This sequence should appear after a sequence of non-printing characters.
	
\001 can be used directly in place of \[ and is recommended as a more portable option
\002 can be used directly in place of \] and is recommended as a more portable option

Below are some examples, each more complicated than the last to show how many options are available. These, of course are still only a few. In these examples we will only use \u, \h, and \W for placing the username, hostname, and base working directory name within our prompt. For example, the base working directory for /some/really/long/path is just path, and the basename for our user's home directory is ~.

Prompt Examples

Any of the below exports can be pasted directly into the terminal to be tested. Once the terminal is closed, these settings will be lost, so no worries about getting back to default. This is a good way to test what would happen if you changed the PS1 within your ~/.bashrc, without actually doing so. If you mess up too bad, just close your terminal and open a new one. If you are logged in via ssh, you'll have to either source ~/.bashrc or log out and back into the server.

Note that when using special characters and symbols, you need to tell bash to interpret these values with a $ before opening your single-quotes, as in export PS1=$'\xe2\x9c\x93'

Note that we do not need to escape hexidecimal characters that will be interpreted. See the below for examples

# Ok
echo -e '\001\033[1;32m\002\xde\x90\x0a\001\033[0m\002'
# Wrong, no need to wrap symbol hex value with `\001` and `\002`
echo -e '\001\033[1;32m\002\001\xde\x90\x0a\002\001\033[0m\002'
# Wrong, hexidecimal symbol is wrapped within `\001` and `\002`
echo -e '\001\033[1;32m\xde\x90\x0a\033[0m\002'

When writing custom prompts, this can become a lot to take in all at once. The following prompt doesn't even use color codes yet, and already it is quite the line -

export PS1=$'\xe2\x94\x8c\xe2\x94\x80\xe2\x94\x80\u@\h\xe2\x94\x80[\W]\n\xe2\x94\x94\xe2\x94\x80\xe2\x95\xbc\$'

What I like to do is split the prompt between several append statements to PS1 within my .bashrc. An example of this is below -

# Printing ┌──
PS1=''
PS1+=$'\xe2\x94\x8c'
PS1+=$'\xe2\x94\x80'
PS1+=$'\xe2\x94\x80'

# Printing kapper@kubuntu-vbox─[~]
PS1+='\u@\h'
PS1+=$'\xe2\x94\x80'
PS1+='[\W]'

# Move to next line
PS1+=$'\n'

# Printing └──╼$
PS1+=$'\xe2\x94\x94'
PS1+=$'\xe2\x94\x80'
PS1+=$'\xe2\x95\xbc'
PS1+='\$'

Alternatively, for practice or playing around, we can create a new file called .practice_prompt with the following contents. Then, we can just run source ~/.practice_prompt to enable the custom prompt from anywhere -

# Printing ┌──
export PS1=''
export PS1+=$'\xe2\x94\x8c'
export PS1+=$'\xe2\x94\x80'
export PS1+=$'\xe2\x94\x80'

# Printing kapper@kubuntu-vbox─[~]
export PS1+='\u@\h'
export PS1+=$'\xe2\x94\x80'
export PS1+='[\W]'

# Move to next line
export PS1+=$'\n'

# Printing └──╼$
export PS1+=$'\xe2\x94\x94'
export PS1+=$'\xe2\x94\x80'
export PS1+=$'\xe2\x95\xbc'
export PS1+='\$'

Splitting your PS1 assignment up not only makes it easier to read, but it suddenly becomes easy to comment out specific sections of the prompt when debugging issues with character spacing or adjusting the final appearance.

Simple Prompt

We can create a bare-minimum and simple export like the below, to test these values before adding any color

# Example of what the prompt will look like
[kapper@kubuntu-vbox ~]$

# Export to use this prompt
export PS1='[\u@\h \W]\$'
Colorized Prompt

We can create a bare-minimum and simple export like the below, to test these values before adding any color

# Example of what the prompt will look like
[kapper@kubuntu-vbox ~]$

# Export to use this prompt
export PS1='\001\033[1;32m\002[\u@\h\001\033[0m\002 \W\001\033[1;32m\002]\$\001\033[0m\002'
Symbols in Prompt

Let's use some symbols to create a more interesting prompt. This prompt is based on the default prompt from the Parrot linux distribution. This prompt will use special symbols, so to begin we use echo ┌ └ ─ ╼ | hexdump -C to get the below output.

[kapper@kubuntu-vbox ~]$echo ┌ └ ─ ╼ | hexdump -C
00000000  e2 94 8c 20 e2 94 94 20  e2 94 80 20 e2 95 bc 0a  |... ... ... ....|
00000010
[kapper@kubuntu-vbox ~]$

Notice we passed three symbols with spaces between them. If we run the command ascii to see the ascii table, we can see that the value of the hexidecimal column for the space character is 20. This is seen in the above output and helps to separate the hexidecimal values of our symbols so we can easily see where one begins and ends. We see that  is e2 94 8c followed by a space 20, then  which is e2 94 94, and another space value of 20. Next, the  symbol is e2 94 80, followed by one more 20 and the final  symbol's hex value of e2 95 bc. We will need to place the hexidecimal values of our special characters in the position we want the symbol to appear within our PS1 export.

Below, we use this information to correctly use symbols in our bash prompt. Note that while pasting the raw symbol will appear to work, it will cause bugs in your prompt. The method below requires more effort, but it will not cause character spacing issues within your prompt.

# Example of what the prompt will look like
┌──kapper@kubuntu-vbox─[~]
└──╼$

# Export to use this prompt
export PS1=$'\xe2\x94\x8c\xe2\x94\x80\xe2\x94\x80\u@\h\xe2\x94\x80[\W]\n\xe2\x94\x94\xe2\x94\x80\xe2\x95\xbc\$'
Symbols and colors in Prompt
# Example of what the prompt will look like 
# NOTE: Color is lost here, but there will be color within your terminal
┌──kapper@kubuntu-vbox─[~]
└──╼$

# Export to use this prompt
export PS1=$'\001\033[1;31m\002\xe2\x94\x8c\xe2\x94\x80\xe2\x94\x80\001\033[1;32m\002\u@\h\001\033[1;31m\002\xe2\x94\x80[\001\033[0m\002\W\001\033[1;31m\002]\n\xe2\x94\x94\xe2\x94\x80\xe2\x95\xbc\001\033[1;32m\002\$\001\033[0;39m\002'
Foreground color codes

This section will cover using escape sequences to change the font color used within your bash prompt

Using the appropriate bash syntax and following the codes below the \001\033[32m\002 escape code will colorize everything green after. Technically, the color code is only the [32m portion, but it needs to be enclosed in \001\033 and \002. \001\033 is the more portable option for \[\e, and \002 is the more portable option for \].

So \001\003[32m\002 is both technically equivalent to and more portable than \[\e[32m\]

Also, the next section covers attributes, which make up the 0 in \[\e[0;32m\]. So any attribute can be applied to any color by changing this leading value, or the 0; can be removed entirely if normal text is used, as in \[\e[32m\].

The following sequences can be used to set attributes that impact the color of text in a bash terminal. Notice that each color has a corresponding light color by changing the leading 3 to a 9. For example, in the color sequence [32m and [92m for green and light green, respectively -

Default color\001\033[0;39m\002
Black\001\033[0;30m\002White\001\033[0;97m\002
Light Gray\001\033[0;37m\002Dark Gray\001\033[0;90m\002
Red\001\033[0;31m\002Light Red\001\033[0;91m\002
Green\001\033[0;32m\002Light Green\001\033[0;92m\002
Yellow\001\033[0;33m\002Light Yellow\001\033[0;93m\002
Blue\001\033[0;34m\002Light Blue\001\033[0;94m\002
Magenta\001\033[0;35m\002Light Magenta\001\033[0;95m\002
Cyan\001\033[0;36m\002Light Cyan\001\033[0;96m\002
Background color codes

This section will cover using escape sequences to change the background color used within your bash prompt. This will have the effect of 'highlighting' the text in a certain color.

The following sequences can be used to set attributes that impact the background color of text print within a bash terminal. Notice that each color has a corresponding light color by changing the leading 4 to a 10. For example, in the color sequence [42m and [102m for green and light green background colors, respectively -

Default color\001\033[0;49m\002
Black\001\033[0;40m\002White\001\033[0;107m\002
Light Gray\001\033[0;47m\002Dark Gray\001\033[0;100m\002
Red\001\033[0;41m\002Light Red\001\033[0;101m\002
Green\001\033[0;42m\002Light Green\001\033[0;102m\002
Yellow\001\033[0;43m\002Light Yellow\001\033[0;103m\002
Blue\001\033[0;44m\002Light Blue\001\033[0;104m\002
Magenta\001\033[0;45m\002Light Magenta\001\033[0;105m\002
Cyan\001\033[0;46m\002Light Cyan\001\033[0;106m\002
Set attributes

Any attribute can be applied to any color by changing the leading 0;, or the attribute value can be removed entirely if normal text is used, as in \[\e[32m\].

The following sequences can be used to set attributes that impact the appearance of text in a bash terminal. Note that the set is technically only [1m but these also need to be wrapped in \001\033 and \002 -

Set bold and bright\001\033[1m\002
Set dim\001\033[2m\002
Set underline\001\033[4m\002
Set blink\001\033[5m\002
Set reverse\001\033[7m\002
Set hidden\001\033[8m\002
Reset attributes

The following sequences can be used to reset attributes that impact the appearance of text in a bash terminal, returning them to normal after the attribute was previously set. Note that the reset is technically only [0m but these also need to be wrapped in \001\033 and \002 -

Reset all attributes\001\033[0m\002
Reset bold and bright\001\033[21m\002
Reset dim\001\033[22m\002
Reset underline\001\033[24m\002
Reset blink\001\033[25m\002
Reset reverse\001\033[27m\002
Reset hidden\001\033[28m\002