
Customising Bash fits in one file: ~/.bashrc. That is where you put your aliases, your PS1 prompt, your functions and your environment variables, read again by every terminal. Bash is the default shell of Debian, Ubuntu and RHEL; macOS, for its part, switched to Zsh in 2019. This page shows the useful settings by hand, then two tools that go further: bash-it for themes and plugins, fzf to search the history. The behaviours described were checked on Debian 13, Ubuntu 24.04 and AlmaLinux 10.
What you will learn
- Configure
.bashrcto customise the prompt, aliases and functions - Customise the PS1 prompt to show useful information
- Install and use bash-it to manage themes and plugins
- Integrate fzf for ultra-fast fuzzy search in the history and in files
History of Bash
Bash, short for "Bourne Again Shell", was released in 1989 by Brian Fox for the GNU project. It succeeds Stephen Bourne's sh, whose syntax it keeps to stay compatible with existing scripts, adding history, completion and many extensions.
Its inclusion in the GNU project made it the natural shell of Linux distributions, and it was long the shell of macOS, until Apple replaced it with Zsh in 2019. Compared with Zsh, Ksh or Tcsh, Bash stands out for its balance between simplicity and features, and above all for its guaranteed presence on servers: it is the shell your administration scripts can assume is available.
Install Bash and configure the shell on Linux
Bash is preinstalled on the three reference distributions: there is nothing to install. Its version shows with bash --version, useful to know whether a recent feature is available. Measured: 5.2.37 on Debian 13, 5.2.21 on Ubuntu 24.04, 5.2.26 on AlmaLinux 10.
bash --versionHow to set Bash as the default shell on Linux
Your login shell is recorded in /etc/passwd, and chsh -s changes it for your account. The command asks for your password, and for an ordinary user only accepts the shells listed in /etc/shells.
chsh -s "$(command -v bash)"chsh is provided by the passwd package on Debian and Ubuntu, by util-linux on AlmaLinux 10. The change applies to the next logins: check it with getent passwd "$USER", whose line must end with the path of Bash.
Customise Bash: tips for the .bashrc file
The ~/.bashrc file is read by every interactive shell that is not a login shell, that is by every terminal you open in a graphical session. Login shells (SSH, console) first read another file, but distributions make them load .bashrc in turn: ~/.profile does so on Debian and Ubuntu, ~/.bash_profile on RHEL and its derivatives (checked in /etc/skel).
Located in your home directory, .bashrc only concerns your account. You define environment variables, aliases, functions and the prompt there; each one has a section below.
Add aliases to simplify commands
Aliases are shortcuts for the commands you type often. They are declared in .bashrc, one per line, with single quotes around the command:
# Alias to show hidden files in long formatalias ll='ls -la'
# Aliases to navigate quicklyalias ..='cd ..'alias ...='cd ../..'
# Alias for complex commands (Debian and Ubuntu)alias update='sudo apt update && sudo apt upgrade -y'An alias added to the file does not exist yet in the open terminal: reload .bashrc to apply it, or open a new terminal. The workings of apt used here are detailed in the apt guide.
source ~/.bashrcCustomise the Bash prompt
The prompt is the line shown before each command. It is set with the PS1 variable, whose backslash sequences are replaced when it is displayed:
# Prompt showing the user, the host and the current directoryexport PS1='\u@\h:\w\$ 'In this example, three sequences are enough to locate the session:
\ustands for the user name.\hstands for the host name.\wstands for the current working directory.
To add colours, you insert ANSI codes, surrounded by \[ and \]: these markers tell Bash that the characters take no room on screen, otherwise long commands wrap badly.
export PS1='\[\e[32m\]\u@\h:\[\e[34m\]\w\[\e[0m\]\$ 'This prompt colours the user and the host in green (32), the directory in blue (34), then returns to the default colour with \e[0m.
Add custom functions
Functions group several commands under a name, and accept arguments where an alias cannot. For example, a function that empties a temporary directory:
clean_temp() { rm -rf ~/temp/* echo "Temporary folder cleaned."}Add it to your .bashrc, then reload it with source ~/.bashrc to use it. Functions are detailed in Bash functions, with their scope traps.
Change environment variables
.bashrc is also used to define environment variables, passed on to the programs you start. The most common case is adding a directory to the PATH:
# Add directories to the PATHexport PATH=$PATH:/usr/local/bin:/opt/scriptsWatch out for a side effect: each source ~/.bashrc adds these directories to the PATH again, which grows with duplicates as you reload. It does no serious harm, but opening a new terminal starts again from a clean PATH.
bash-it: a framework to customise Bash easily
Overview
bash-it is an open source framework that brings together, for Bash, ready-to-use aliases, plugins, prompt themes and completions. It saves you configuring everything by hand, at the cost of a GitHub repository cloned in your home directory.
It is made of four families of modules, which can be turned on one by one with bash-it enable:
- Aliases: predefined shortcuts to simplify common commands.
- Plugins: modules that add specific features (e.g. Git, Docker support).
- Themes: customisation of the prompt to make the terminal more informative and good-looking.
- Completions: improvements of autocompletion for complex commands.
Install and configure bash-it
The installation takes four steps, without root rights: clone the repository, run its installation script, turn it on in .bashrc, then reload.
-
Clone the repository into
~/.bash_it:Terminal window git clone --depth=1 https://github.com/Bash-it/bash-it.git ~/.bash_it -
Run the installation script, which offers to back up your existing
.bashrcbefore changing it:Terminal window ~/.bash_it/install.sh -
Turn bash-it on by hand if you declined the automatic change of
.bashrc, by adding this line to it:Terminal window source ~/.bash_it/bash_it.sh -
Reload the configuration:
Terminal window source ~/.bashrc
bash-it configuration
bash-it ships many modules, most of them turned off by default. The bash-it show command lists a catalogue with the state of each entry, and bash-it enable turns on the one you want.
Turn on and manage aliases
The alias sets turned on are stored in ~/.bash_it/aliases/enabled. bash-it show alias prints the catalogue, with [ ] for an inactive set and [x] for an active one:
bash-it show alias
Alias Enabled? Descriptionag [ ] the silver searcher (ag) aliasesansible [ ] ansible abbreviationsapt [ ] Apt and dpkg aliases for Ubuntu and Debian distros.atom [ ] Atom.io editor abbreviationsbash-it [ ] Aliases for the bash-it command (these aliases are automatically included with the "general" aliases)bolt [ ] puppet bolt aliasesbundler [ ] ruby bundler
bash-it enable alias ansibleThe last command turns on the ansible alias set, which abbreviates common Ansible commands. The same principle applies to every set listed.
Turn on plugins
Plugins add functions and behaviours to the terminal. bash-it show plugins lists their catalogue; the base plugin, marked [x], is on by default:
bash-it show plugins
Plugin Enabled? Descriptionalias-completion [ ]autojump [ ] Autojump configuration, see https://github.com/wting/autojump for more detailsaws [ ] AWS helper functionsbase [x] miscellaneous tools...
bash-it enable plugin dockerThis command turns on the Docker plugin, which provides helper functions and completions to manage your containers.
Turn on completions
Completions let Bash suggest the options and arguments of a command when you press Tab. To turn on the one for SSH:
bash-it enable completion sshThe Tab key then completes the known host names after ssh, which makes typing your connections easier.
Customising themes
A bash-it theme replaces your PS1 with a richer prompt: user, machine, current directory, Git state, sometimes the time or the exit code. The available themes are the subfolders of ~/.bash_it/themes, each holding the .bash file that defines it.
ls ~/.bash_it/themes
90210 codeword font modern powerline-naked sexyagnoster cooperkid gallifrey modern-t powerline-plain simpleatomic cupcake githelpers.theme.bash modern-time powerturk sirupaxin demula gitline morris primer slickbakke dos hawaii50 n0qorg pro standardbarbuk doubletime inretio newin pure tonkabase.theme.bash doubletime_multiline iterate norbu purity tonotdobinaryanomaly doubletime_multiline_pyonly kitsune nwinkler radek tylenolbira dulcie lambda nwinkler_random_colors rainbowbrite wanelobobby duru liquidprompt oh-my-posh ramses zitronbobby-python easy luan p4helpers.theme.bash rana zorkbrainy elixr mairan parrot redlinebrunton emperor mbriggs pete rjorgensoncandy envy metal powerline robbyrussellclean essential minimal powerline-multiline roderikAmong the most used are powerline, bobby and pure. The theme is chosen with the BASH_IT_THEME variable of .bashrc, for example for powerline:
export BASH_IT_THEME='powerline'Then reload your configuration so that the new theme replaces the current prompt:
source ~/.bashrcAdapt the theme to your needs
Each theme is an editable .bash file in ~/.bash_it/themes. To add a piece of information to it, you write a function and inject it into the prompt. Example with the battery state, read by acpi when installed:
# Add a battery status segmentbattery_status() { if command -v acpi &> /dev/null; then acpi -b | grep -o '[0-9]*%' | head -n 1 fi}export PS1='$(battery_status) '$PS1The command -v acpi test avoids an error on machines without a battery or without the tool. Keep your changes in a copy of the theme: an update of bash-it through git pull would overwrite the original file.
Using fzf
fzf is an interactive filter on the command line: it shows a list and narrows it as you type, without requiring the exact name. Integrated into Bash, it replaces the Ctrl+R history search with a filterable list, and adds Ctrl+T to insert a file path.
Installing fzf
fzf is packaged on every reference distribution, but not in the same repositories nor in the same version, and the version decides how to turn it on. Measured: 0.60 on Debian 13, 0.44 on Ubuntu 24.04, and 0.58 from EPEL on AlmaLinux 10, where dnf install fzf fails without that repository.
-
Debian/Ubuntu:
Terminal window sudo apt install fzf -
RHEL and derivatives (the package comes from EPEL):
Terminal window sudo dnf install epel-releasesudo dnf install fzf -
macOS with Homebrew (in French):
Terminal window brew install fzf
Turn on the fzf plugin with bash-it
If you use bash-it, a dedicated plugin loads fzf for you. It assumes fzf is already installed by the package manager:
bash-it enable plugin fzfThen reload .bashrc: the fzf shortcuts are active without touching the file yourself.
Add fzf to the .bashrc file
Without bash-it, turning it on takes a few lines of .bashrc, which depend on the installed version. Since fzf 0.48, the fzf --bash command itself produces the code of the shortcuts and of the completion: that is the case of Debian 13 and AlmaLinux 10. Ubuntu 24.04, with its version 0.44, does not know it: you must load the files provided by the package there.
# fzf 0.48 and later (Debian 13, AlmaLinux 10 with EPEL)eval "$(fzf --bash)"
# older fzf (Ubuntu 24.04): files shipped by the packagesource /usr/share/doc/fzf/examples/key-bindings.bashsource /usr/share/bash-completion/completions/fzf
# Appearance: 40 % height, list from top to bottom, borderexport FZF_DEFAULT_OPTS="--height 40% --reverse --border"Keep only the block that matches your system: fzf --version tells you which. The FZF_DEFAULT_OPTS variable, on the other hand, applies to every version.
Reload the configuration
After changing your .bashrc file, reload it, then try Ctrl+R: a filterable list of your history must open instead of the classic search.
source ~/.bashrcWriting Bash scripts: automation and good practices
A Bash script is a file that chains commands, to automate a repetitive task. The "Write Bash scripts" module of this path covers it in detail; this section only recalls the basics, to show what your .bashrc has in common with a script.
A script starts with the shebang line, which tells the system which interpreter must run it:
#!/usr/bin/env bash
echo "Hello, this is a simple Bash script"The arguments passed to the script arrive in $1, $2, and so on, which makes the script reusable with different values:
#!/usr/bin/env bash
user_name=$1echo "Welcome, $user_name!"The control structures if, for and while steer the execution according to the state of the system, for example the existence of a file:
#!/bin/bash
if [ -f "/etc/passwd" ]; then echo "The file /etc/passwd exists."else echo "The file /etc/passwd does not exist."fiTo run it directly, a script must be made executable, then started with its path:
chmod +x my_script.sh./my_script.shFurther in writing Bash scripts
Two lessons of the scripts module extend these basics. They come before this one in the path, and you can go back to them at any time:
- Write a shell script: the basics of script writing and the structure of a clean script.
- Robust Bash scripts:
set -euo pipefail, input validation,trapand safe temporary files.
Going further with Bash: tools and advanced customisation
Two tools often come on top of .bashrc when customisation reaches its limits. asdf (in French) is a version manager that installs several versions of the same language or tool side by side, and switches from one to the other depending on the project. direnv automatically loads and unloads environment variables according to the current directory, which avoids the forgotten export when you change project.
Combined with bash-it, these tools produce a working environment very close, in comfort, to what Zsh offers natively, without changing shell or relearning a syntax.
Troubleshooting
Almost every customisation problem comes from a file not reloaded or from a line that does not match your tool's version. The reflex: open a new terminal, which reads everything again from scratch.
| Symptom | Likely cause | Solution |
|---|---|---|
Changes to .bashrc do not apply | The file was not reloaded after the change | Run source ~/.bashrc or open a new terminal |
| The prompt shows odd characters, long lines wrap badly | PS1 colour codes not enclosed | Enclose each colour code with \[ and \] |
bash-it does not load the plugins | The plugins are not turned on | Run bash-it enable plugin <name> then source ~/.bashrc |
unknown option: --bash when the terminal starts | fzf older than 0.48 (Ubuntu 24.04) | Load /usr/share/doc/fzf/examples/key-bindings.bash instead |
Ctrl+R stays the classic search | fzf shortcuts not loaded | Add eval "$(fzf --bash)" or the key-bindings.bash file to .bashrc |
dnf install fzf does not find the package | fzf comes from EPEL on RHEL and its derivatives | sudo dnf install epel-release, then run it again |
Key points
- The
~/.bashrcfile is the central place to customise Bash, read by every interactive terminal, including login sessions through~/.profileor~/.bash_profile. - Aliases and functions in
.bashrcautomate repetitive commands. - The PS1 prompt can show user, host and directory; its colour codes are enclosed in
\[and\]. - bash-it provides a complete, ready-to-use framework of themes and plugins.
- fzf greatly improves history search; its version decides how to turn it on.
Knowledge check
Check that the essentials of this guide stuck. The questions cover only what has just been explained here.
Knowledge check
Check what you have learned with this interactive quiz
How it works
- The timer starts when you click Start
- Multiple choice, true/false and short answer questions
- You can move between questions
- Detailed results are shown at the end
Starts the quiz and the timer
Review
(0/0)Score by domain
A domain groups several guides and gets several questions, so its score is more reliable than a per-topic score, which often rests on a single question.
Summary
Strengths
No topic passed at 80% on at least two questions yet.
Weak areas
No topic below the pass mark.
Recommended next
Hints before you try again?
Continue the course: Install and configure Zsh on Linux
A new full quiz with random questions
Work again only on the questions you missed