Bash History Enhanced — how to use command line history more effectively

Paolo Cozzi
5 min readMay 23, 2020
Photo by Sai Kiran Anagani on Unsplash

Recently, I was talking with my collegues and they were impressed that I could find a linux command I typed two years ago in my bash history. They think that I was kidding them, but I spent a lot of time in managing bash history and you could imagine how can be useful to track very all the complex linux commands you typed recently (or not).

In my work experience I spend a lot of time with bash terminal, facing different aspects like programming, maintaining our work infrastructure or performing data analysis. Since I move from different projects I found more useful relying on my command history instead of typing commands manually since I noticed that I tend to repeat similar commands I used before, and it will take a certain amount of time remember the exact parameter I used or looking in the man pages what that particular option stand for.

The Bash History

The bash history is a feature which can track every command you type in a bash shell, and is written into a file (.bash_history) by the shell itself when is closed, in order to be restored when a new terminal is started. Only a limited set of commands can be tracked in memory and in the history file, and when this limit is reached old commands will be discarded in order to track new ones. You can list the commands you typed in bash history, filter using “grep”, “tail” or “head” and call the exact command you type before by adding a “!” before the history number. You can also change something before executing the old command. Remeber: when you recall an old command this will be immediately executed, if you don’t want to execute a command type “:p” after your history command:

# Display your bash history
$ history
1 cd
2 ls -a
3 cd /home/
4 ls
5 cd
# Filter for a certain command with grep
$ history | grep docker | grep debian
675 docker pull debian
676 docker run -ti debian:latest /bin/bash
942 docker run -ti --rm -v $PWD:/data debian:latest /bin/bash
2567 docker run -ti --rm debian:jessie /bin/bash
3415 docker rmi debian:jessie
6978 docker pull debian:buster
6979 docker tag debian:buster debian:latest
# call exactly command 676 and execute it
$ !676
docker run -ti debian:latest /bin/bash
# perform a global substitution before executing a command
$ !676:gs/latest/buster/
docker run -ti debian:buster /bin/bash
# perform a global substitution but don't execute the command
$ !676:gs/latest/buster/:p
docker run -ti debian:buster /bin/bash

Check more info on bash history here: https://catonmat.net/the-definitive-guide-to-bash-command-line-history

Search for a command with arrow keys

The most elementary tips in using bash history is to use arrow keys. From your terminal, without typing anything you could use “[Arrow Up]/[Arrow Down]” to browse up and down your bash history . This is the most simple and underrated tip on bash history

Interactive searches

You can search in bash history for lines containing a specified string. Type “[ctrl]+r” and start typing the characters of the desidered command to have the first match. You can type “[ctrl]+r” again and again to cycle backword accross different matches. To search forward in modern terminal you have to activate a particular feature by setting:

stty -ixon

in your “.bashrc”, as described in this StackOverflow response. Now you can search your pattern forward with “[ctrl]+s” without freezing your terminal (if you have your terminal freezed, try “[ctrl]+q”). “ESC” or “[ctrl]+j” will terminate the search leaving the last matched line, RET will execute the matched commands and “[ctrl]+g” will abort the search to return to the original line. More info in incremental searches could be found at Searching for Commands in the History.

Bash history optimization

The two main environment variables that affect history size are:

HISTSIZE=10000
HISTFILESIZE=10000

The first is the size of the history in memory and the second affects the history file size when a terminal is closed and new commands are added to history file. Raising these two limits is the first step to track more commands but, do you need to track every “ls” I typed? Should I track when I search in history? and what if I recall a “rm” command in a wrong place? The following environment variable lets to ignore certain commands from being added in bash history:

HISTIGNORE=”ls:ll:exit:clear:cd:top:htop*:history*:rm*”

Simply add every command you want to ignore to this environment variable using “:” as separator. “*” is considered for pattern matching, and in the previous example I can’t add the rm command and its variations in my bash history.

These are other useful options for tuning out bash history in your shell:

# don't put duplicate lines or lines starting with space 
# in the history. See bash(1) for more options HISTCONTROL=ignoreboth:erasedups
# append to the history file, don't overwrite it
shopt -s histappend
# Write a multi line command in a single line
shopt -s cmdhist

Advanced bash history optimization

There are other custom features I used for tuning more my bash history. For example, I don’t want to keep multiple copies of the same commands I typed from different terminal sessions. Moreover, when I recall a command I want to remove duplications and put it into first position of the history file, in order to be easily retrieved and prevent its removal when size is near its limits. These are a series of bash functions that are executed every time I start a new shell:

Conclusions

Bash history is the place where all commands typed in a linux terminal are kept. We can search in bash history in order to recall a particular command we did, and this search can be enhanced in order to store more useful commands or avoid to track unuseful ones. These are some tips I found useful in managing bash history, you could find all my bash history settings here:

References

The Definitive Guide to Bash Command Line History: https://catonmat.net/the-definitive-guide-to-bash-command-line-history

Bash History Facilities: http://www.gnu.org/software/bash/manual/html_node/Bash-History-Facilities.html#Bash-History-Facilities

Searching for Commands in the History: http://www.gnu.org/software/bash/manual/html_node/Searching.html

Search forward in bash history: https://stackoverflow.com/a/791800/4385116

--

--