A better command history
Tags: showdev, bash, webdev, tooling
Published: 2021-02-13 00:03:20

If you spend a lot of time at the command line, you know how powerful the command history is. Especially if you use [`Ctrl + r`, and other advanced history-related features](https://www.digitalocean.com/community/tutorials/how-to-use-bash-history-commands-and-expansions-on-a-linux-vps).

As powerful as the command history is, it could be a *lot* better.

### What's wrong with history?

The two biggest problems with the command history are:
1. It is [very](https://unix.stackexchange.com/questions/131504/how-to-sync-terminal-session-command-history-in-bash) difficult to build a central command history across multiple terminal sessions and multiple computers.
2. Command histories only store the commands themselves. They do not store the output of the commands or even the exit code.

Command history is great when running commands that you use frequently and are already quite familiar with.

If you want to perform an operation that you are unfamiliar with and very rarely use, your command history tends to be useless. Especially when you can't remember which terminal or even machine you ran that operation on previously.

### Storing command history in Bugout

For context, [Bugout.dev](https://bugout.dev) is an automated knowledge base for developers and software teams. It is free to use for individuals and for small teams (up to 5 members).

Bugout has a very simple API that you can use to add knowledge into your knowledge base and it offers search over your knowledge base out of the box.

Bugout comes with a command line tool called `bugout`:
{% github bugout-dev/bugout-go %}

`bugout` has a command, `bugout trap`, which captures a command from your terminal into your knowledge base. `bugout trap` not only captures the command, but also its:
1. exit code
2. stdout
3. stderr
4. (optionally) the environment variables it was run with
5. (optionally) any additional tags you would like to associate with it

Below are some examples of how I use `bugout trap` to turn my knowledge base into a centralized command history:

#### Example: Capturing API requests, responses, and headers with curl

{% asciinema 390936 %}

The link takes us to the new knowledge base entry:
![GitHub rate limit request, response, and headers](https://dev-to-uploads.s3.amazonaws.com/i/stkkorxg51zb3mfldpjv.png)

#### Example: Image format conversions

I rarely use [`ImageMagick`](https://imagemagick.org/index.php) directly - and never remember that its shell command is `convert`!

I only had an SVG version of the cover image for this post and wanted to use ImageMagick to transform it to PNG (dev.to does not accept SVG images).

I searched my history for occurrences of `svg` or `png`: `history | grep svg` and `history | grep png`. Unfortunately, I only found a bunch of commands where I opened image files: commands like `xdg-open <filename>.svg` and `xdg-open <filename>.png`.

This time, when I figured it out, I used `bugout trap`:
{% asciinema 390937 %}

The entry:
![ImageMagick command to convert SVG to PNG - ImageMagick is pretty awesome and easy to use!](https://dev-to-uploads.s3.amazonaws.com/i/nessubb7vqv72kpnys1m.png)

Best of all, we can search this history from our command line and view it in our editor:
{% asciinema 390938 %}

Note how we can filter the search by exit code using `"tag:exit:0"` in the search query. We can also restrict our search only to invocations that caused errors by using the query `"!tag:exit:0"`. This is very powerful when working with teammates to debug an issue with a command.

#### Example: Tracking production database migrations

At Bugout, we are heavy [Postgres](https://www.postgresql.org/) users. Our backend is written in Python. We use [SQLAlchemy](https://www.sqlalchemy.org/) to interact with our database and [Alembic](https://alembic.sqlalchemy.org/en/latest/) to manage our database migrations.

We run migrations manually in production, and `bugout trap` is very useful to keep a record of when each database migration was run so the whole team can see. This is how we use it:
```bash
bugout trap --title "Database migration: $(alembic history | head -n1)" --tags db,migration,prod -- \
    alembic upgrade head
```

Trapping commands we run in production into our team's knowledge base helps us stay synchronized across 15 time zones.

### Try it yourself

If this workflow sounds compelling to you, you can try it out yourself. Bugout is free for individual developers (and for small teams), so all you have to do is sign up for an account at https://bugout.dev.

Reach out to me in the comments if you need any help setting up!

- - -

*Thank you, @nickmaris , for [suggesting I create this kind of content](https://dev.to/nickmaris/comment/1b5eh).*