Halloween DealsAmazon USHalloween week deals: useful picks before month-endAmazon US: current deals, useful picks and tech finds.Check DealsWindows FixRecommendedWindows errors stealing your time? Find the fix fastScan stability, cleanup and performance issues.Fix NowHalloween DealsAmazon USOctober picks are moving - compare before checkoutAmazon US: current deals, useful picks and tech finds.See Picks×
FREEDOM251

Freedom251 › Blog › Bash

How to Customize Your Bash Prompt on a Linux VPS (PS1, Colors, Git, and Dynamic Status)

By Freedom251 Team · · 10 min read

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Your Bash prompt is controlled primarily by PS1. Set it temporarily to test a design, then place the working assignment in the interactive startup file for your VPS account—usually ~/.bashrc—and reload the file. A useful prompt identifies the account, host, directory, and privilege level without making command editing difficult.

What Bash prompt variables control

Bash uses several prompt variables for different interactive situations. They are ordinary shell variables, so you can inspect or assign them from a terminal.

As an Amazon Associate I earn from qualifying purchases.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Variable When it appears Typical use
PS1 Before Bash reads a normal command Your primary, everyday prompt
PS2 When Bash is waiting for more input, such as after an unfinished quote or a trailing backslash Make continuation lines visually distinct
PS0 In interactive contexts before a command is executed Specialized command-entry feedback
PS4 When execution tracing is enabled with set -x Identify traced commands and their nesting

For most VPS administration, change PS1 first. Bash expands and displays PS1 before reading each command. It reads interactive startup files when an interactive shell starts, which is why a setting in a non-interactive script does not necessarily change the prompt in your SSH session.

Inspect the shell and existing prompt before editing

Run these commands inside the interactive Bash session whose prompt you want to change:

printf 'shell=%snPS1=%qn' "$SHELL" "$PS1"
bash --version | head -n 1

The first line shows the account’s login-shell setting, while PS1=%q displays an escaped representation that is easier to copy and inspect. The second command confirms the Bash version currently available in that session. If the session is running another shell, Bash-specific escapes and startup behavior will not apply until you start Bash.

Before changing a distribution-provided configuration, look at the relevant part of ~/.bashrc and any files it sources. VPS images often add aliases, completion, color logic, or a pre-existing PROMPT_COMMAND. Keep those lines and add your prompt code in a clearly marked section rather than replacing the whole file.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use Bash prompt escapes to show useful context

Prompt escapes are expanded whenever Bash displays the prompt. The most useful ones for a server are:

Escape Displays Why it helps on a VPS
u Current username Shows which account will own new files and run commands
h Short hostname Distinguishes hosts without adding the entire domain name
H Full hostname Useful when short hostnames are ambiguous
w Current working directory, with the home directory abbreviated as ~ Prevents commands from being run in the wrong directory
W Basename of the current directory Keeps a compact prompt in deep trees
d Date in Bash’s standard date format Provides a rough session-date cue
t Current time in 24-hour HH:MM:SS form Useful for observing when commands are entered
n A newline Separates a long identity/path line from the command-entry line
$ $ for a regular effective user or # for an effective root user Provides an immediate privilege warning

These escapes are evaluated by Bash, not by the terminal emulator. Keep them in the value of PS1 so the directory and privilege marker update as your session changes.

Test a prompt without making a permanent change

Assign a prompt directly in the current shell. This changes only that shell process and disappears when the session ends:

PS1='u@h:w$ '

The result has the form user@host:/path$ for a regular account and changes the final character to # when the effective user is root. Single quotes are important here: they keep the backslashes intact until Bash expands the prompt at display time.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

A two-line design gives the command line more horizontal space:

PS1='nu@h w$ '

The leading newline leaves command output above the next prompt and puts identity and location on a fresh line. Try several designs while recalling and editing a long command; a prompt that looks attractive with an empty line may become awkward when the command itself wraps.

To return to the startup-defined value during testing, start a new shell or source the file that normally defines your prompt. If you are experimenting as root, test the same design in a regular account as well; the $ marker is intended to make that distinction visible.

Make the tested prompt permanent

For an interactive Bash session, ~/.bashrc is the usual place for an account-specific prompt. Confirm the file used by your VPS image before editing, because distributions and account setups can source startup files in different arrangements.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  1. Back up the file.
    cp ~/.bashrc ~/.bashrc.bak
  2. Append the tested assignment.
    printf "nPS1='\u@\h:\w\$ 'n" >> ~/.bashrc
  3. Reload the interactive configuration.
    . ~/.bashrc

The dot command reads the file in the current shell, so you do not have to disconnect and reconnect. If the prompt does not change, inspect the file for a later PS1= assignment, a conditional that runs only for interactive shells, or another startup file that overwrites your value. Keep the prompt assignment after the logic that should remain authoritative, or adjust that existing logic instead of creating competing assignments.

Use an interactive guard when putting prompt code in a file that might also be sourced by non-interactive shells:

if [[ $- == *i* ]]; then
  PS1='u@h:w$ '
fi

This prevents prompt-only settings from affecting commands run without a terminal. Do not blindly copy this block over an image’s existing startup code; merge it with the file’s current structure.

Add color without breaking command-line wrapping

ANSI color sequences take bytes in the terminal but occupy zero visible columns. Bash must be told which parts of PS1 do not print; otherwise it miscalculates the cursor position and long commands can wrap onto the wrong line.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Put every non-printing control sequence between [ and ]:

if [[ $- == *i* ]]; then
  BLUE='[e[34m]'
  RESET='[e[0m]'
  PS1="${BLUE}u@h${RESET}:w$ "
fi

Here the account and hostname are blue, while the path and privilege marker use the terminal’s normal color. The variables include the width markers, so the prompt assignment remains readable. You can choose another ANSI color code, but keep the same wrapping rule for every non-printing sequence.

Test color by recalling a command longer than one terminal line, moving the cursor with the arrow keys, inserting text in the middle, and resizing the terminal. If the cursor jumps, characters overwrite one another, or the wrap point is visibly wrong, check that each opening [ has a matching closing ] and that no color reset was omitted.

Color should communicate a decision, not decorate every character. A distinct root color or a colored hostname can prevent mistakes when several SSH windows are open; excessive colors reduce contrast and make copied terminal output harder to read.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Keep deep directory paths readable

A full w value is useful until a deployment path consumes most of the terminal width. Bash provides PROMPT_DIRTRIM to limit the number of trailing directory components shown when it expands w or W:

PROMPT_DIRTRIM=3
PS1='u@h:w$ '

With this setting, Bash abbreviates removed leading components with an ellipsis and retains the requested number of trailing components. The prompt still updates as you change directories, but the visible path is compact enough to leave room for a command. Choose a value that preserves the project or release directories most useful to you; a smaller value is shorter, while a larger value gives more location context.

If you routinely work in one repository, a two-line prompt or W may be clearer than hiding too much of a full path. Do not remove the path entirely on an administrative account unless you have another reliable way to confirm your location.

Show the previous command’s exit status

PROMPT_COMMAND runs immediately before Bash prints the primary prompt. That hook can inspect the status of the command that just finished and alter PS1 accordingly. A minimal indicator is:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
prompt_status() {
  local status=$?
  if (( status == 0 )); then
    PS1='u@h:w$ '
  else
    PS1="(status ${status}) u@h:w$ "
  fi
}
PROMPT_COMMAND=prompt_status

The first statement saves $? before any other command in the function changes it. A failed command then appears as, for example, (status 2) user@host:/path$ on the next prompt. This is especially useful after package operations, deployment commands, or scripts whose output is easy to miss.

Many VPS images already use PROMPT_COMMAND for title updates, directory tracking, or other prompt logic. Replacing it outright can disable those features. Inspect its existing value and preserve or incorporate the current entries when adding your function. Also keep hooks short: they run before every primary prompt, so an expensive command will make every command feel slower.

If you prefer a less intrusive design, show a symbol or color only on failure rather than printing the numeric status every time. Whatever indicator you choose, make sure it is unambiguous and remains visible when the prompt wraps.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Add the current Git branch selectively

A branch name is useful inside repositories but unnecessary in ordinary system directories. The following function asks Git for the short branch name and returns nothing outside a repository or when the repository is in a detached state:

git_branch() {
  local branch
  branch=$(git symbolic-ref --quiet --short HEAD 2>/dev/null) || return
  printf ' (%s)' "$branch"
}

prompt_with_branch() {
  local status=$?
  if (( status == 0 )); then
    PS1="u@h:w$(git_branch)$ "
  else
    PS1="(status ${status}) u@h:w$(git_branch)$ "
  fi
}
PROMPT_COMMAND=prompt_with_branch

The function runs Git before each prompt, so keep it optional on large repositories or slow network-mounted filesystems. It deliberately asks only for the branch reference; it does not inspect whether the working tree has uncommitted changes. If branch information becomes distracting, remove the command substitution and retain the simpler path-based prompt.

When combining this example with an existing status function or another PROMPT_COMMAND, use one coordinated hook rather than assigning the variable multiple times. The last assignment wins unless you explicitly preserve earlier entries.

Choose a prompt design by risk and workload

Design Information shown Best fit Trade-off
Minimal Current directory and $/# Short commands and small terminals Does not identify the host or account
Identity-first User, short hostname, directory, privilege marker Administrators with several VPS sessions Longer line in deep paths
Two-line Identity and location above the command-entry line Long paths or frequent command editing Consumes an extra screen line
Status-aware Identity prompt plus the previous exit status on failure Deployment and troubleshooting work Requires a prompt hook on every command
Git-aware Identity, path, and branch inside repositories Development VPS sessions Runs a Git query before each prompt

Evaluate a design against five practical criteria: can you identify the host and privilege level at a glance, can you still see enough of the path, does it remain readable in monochrome output, does dynamic work stay inexpensive, and will it behave on the VPS image’s actual startup files?

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Troubleshoot common prompt problems

The change works once but disappears after reconnecting

An assignment entered at the command line affects only that shell. Put the tested value in the interactive startup file for the account that opens the SSH session, then reload it. If a login wrapper starts another shell, inspect which startup files that shell reads and whether a later file overwrites PS1.

The prompt shows literal backslashes or expands too early

Use single quotes around a basic assignment such as PS1='u@h:w$ '. Double quotes are appropriate when constructing a value from variables or command substitutions, but they change when shell expansion occurs. Check the stored value with printf 'PS1=%qn' "$PS1".

Long commands wrap incorrectly

Inspect every color, bold, title, or other terminal control sequence. Each non-printing portion must be enclosed by [ and ]. Remove all color temporarily; if wrapping becomes correct, add sequences back one at a time. Also test after resizing the terminal and after recalling a long command.

The host or privilege marker is missing

Confirm that the prompt contains h or H and $, rather than a hostname or dollar sign captured once during setup. The escape forms update when the session context changes. If you use sudo, remember that it runs one command with elevated privileges; it does not necessarily turn the current shell into a root shell, so the prompt may correctly remain a regular-user prompt.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The prompt becomes slow

Review every command in PROMPT_COMMAND and every command substitution in PS1. Git queries, filesystem scans, network calls, and version-manager hooks can run before every primary prompt. Remove work that does not help your next decision, and avoid external services in a prompt hook.

A distribution feature stopped working

Look for existing PROMPT_COMMAND, color variables, and sourced files in ~/.bashrc. A later PS1= assignment may replace yours, while a new PROMPT_COMMAND=... assignment may replace the image’s hook. Restore the backup if necessary, then combine your logic with the existing configuration instead of deleting it.

Continuation lines are confusing

Set PS2 to a visibly different marker, for example:

PS2='> '

Now an unfinished quote, pipeline, or multiline command is clearly separate from a fresh primary prompt. Keep it short so multiline commands remain easy to paste and edit.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

A safe final configuration example

The following combines an interactive guard, path trimming, color width markers, and a failure indicator without requiring a network service:

if [[ $- == *i* ]]; then
  PROMPT_DIRTRIM=3

  prompt_status() {
    local status=$?
    local blue='[e[34m]'
    local red='[e[31m]'
    local reset='[e[0m]'

    if (( status == 0 )); then
      PS1="${blue}u@h${reset}:w$ "
    else
      PS1="${red}(status ${status})${reset} ${blue}u@h${reset}:w$ "
    fi
  }

  PROMPT_COMMAND=prompt_status
  PS2='> '
fi

Test this in a disposable shell before placing it in your permanent configuration. If the VPS already defines a prompt hook, merge the function with that hook and preserve its behavior. The right prompt is the one that makes host, account, location, and failure state obvious while leaving the command line reliable to edit.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

BashCommand LineLinux administrationLinux VPSPS1SSH

Leave a Reply

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

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Recommended PC Tool
Recommended PC Tool
Windows Errors? Fix Them Before They SpreadFree repair scan
Crashes, No Sound, or Screen Glitches?Free driver scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.