Making history

Save a transcript of your shell session after the fact

Brett Weir Dec 8, 2022 4 min read

Sometimes you do something in your terminal that turns out to be really awesome, and you want to save it. You could have opened a session with script, or logged your session otherwise. But one of the simpler ways to get the important bits is with the Bash history command:

history

Everything you've ever typed into the shell ends up here, up to a configured limit, usually around 1000 by default. Now you can see how you got to where you are:

$ history
 1403  cd workstation/
 1404  ls
 1405  code .
 1406  ssh --help
 1407  history

You can use this command wherever a shell is available, like on your desktop, embedded devices, and even inside containers, making it great for capturing history whenever you need to.

Taking a snapshot

This output is great for writing tutorials, but the line numbers are annoying. We can remove them by piping the output to the cut command. We include -c 8-, which instructs cut to keep only the eighth character and onward:

history | cut -c 8-

There are probably smarter ways to do this, but this way is easy to remember and easy to type.

The following is an example of what would be printed:

$ history | cut -c 8-
cd workstation/
ls
code .
ssh --help
history

You can then remove irrelevant commands, like spurious --help commands and duplicate cd commands, which we'll talk about in the next section.

Removing duplicates

Sometimes you might have many instances of the same command. This often happens when you're trying to figure out what packages are required to build something successfully, like below:

$ history | cut -c 8-
apt-get update
apt-get install
apt-get install build-essential
apt-get install libpq-dev
apt-get update
apt-get update -y
apt-get install
apt-get install libqmi-proxy
apt-get update

Not very easy to decipher. But you can expand the history command further by piping it to sort like the following:

$ history | cut -c 8- | sort -u
apt-get install
apt-get install build-essential
apt-get install libpq-dev
apt-get install libqmi-proxy
apt-get update
apt-get update -y

This will eliminate duplicate commands and make it easier to get the essential commands from your transcript. You can once again manually remove spurious entries.

Removing spurious entries

There isn't a good way to do this; manual removal is one approach. If you have enough instances of a certain command, you can use ad-hoc grep statements to thin them out.

Your history log might have stuff like this:

$ history | cut -c 8-
ls
code .
ls
cd
ls
cd Projects/
ls
cd ../Godot/
ls
du -hs *
cd ..
ls

Even after sorting, there's still some noise:

$ history | cut -c 8- | sort -u
cd
cd ..
cd ../Godot/
cd Projects/
code .
du -hs *
ls

Appending a few targeted grep commands will get you what you need:

$ history | cut -c 8- | sort -u | grep -v '^cd'
code .
du -hs *
ls

Clearing history

Bash saves everything whenever you hit enter, but sometimes you don't want it to. Perhaps you set a command-line option or an exported variable value to a password that you don't want stored in plain text. When that happens, you can clear the history by doing:

history -c

Bash saves to the history when the terminal session ends, not during, so clearing history is most effective when you have no other login sessions open. Keep in mind that each user account has its own history, so if your session involves logging in as root via su, for example, you'll need to clear that history as well.

If you're worried, you can also manually delete the history file:

rm -f ~/.bash_history

Or if you're really paranoid, you can shred it first:

shred ~/.bash_history
rm -f ~/.bash_history

Tags

#bash