ISO27001:2013
Certified Supplier

FIND OUT MORE

We're an ISO27001:2013 Certified Supplier

blog-post-featured-image

At some point, most of us will use the command line on our Linux systems. There’s something beautiful about the simple elegance of such a tool. What you may not realise is that the command line is also good for people being a little bit lazy; there is a history of previous commands.

The most basic thing to try is using the up (and down) arrow keys while sat at a prompt. Up scrolls into the past, showing the last command executed, then the command before that, then the  command before that… Down brings you closer to the present, so if the command you wanted is missed, it’s easy to get back. Some terminals don’t much like arrow keys – one or two map the ‘up’ arrow key to ^[[A, for example – but the programmers of the Bash shell knew this day would come. ^P (or Ctrl+p) scrolls into the past, and ^N scrolls towards newer commands. Simple enough, right?

By default Bash only stores around 500 previous commands in memory (and the same on disk). That could be exceeded even in just one particularly determined shell session! In the event of the history size being exceeded, Bash works on a FIFO principle – first in, first out – so the oldest commands get pushed away and newer ones slot in at the bottom. The number of commands  remembered can be changed with the HISTSIZE environment variable, and the number of commands written to the history file (more on that later) is controlled by HISTFILESIZE. Storing a large history doesn’t have as much of an impact as you might think, in terms of either disk usage or startup time; it’s generally well worth keeping a longer history.

A history lesson

The history file can be controlled by the HISTFILE environment variable, and defaults to ~/.bash_history. This file is a list of commands which have been run. By default, the history is only written to disk when the shell process exits, and overwrites the existing history file. This isn’t ideal – especially for users who have multiple terminal sessions on a host simultaneously – and can be changed with more environment variables. The shopt -s histappend command ensures that the history isn’t overwritten: instead it’ll be appended to the previous contents. To write to the file after every command, rather than when the shell process exits, include history -a in the PROMPT_COMMAND environment variable. Be aware, however, that this will stop  any resemblance of a linear history if you have (and are using) more than one session.

As an example, imagine session one is making some changes in Puppet:

and session two is making some changes to some other files:

Together, this history could wind up looking like the below:

Nothing like what actually happened!

A couple of other useful environment variables to be aware of are HISTCONTROLHISTIGNORE, and HISTTIMEFORMAT. HISTCONTROL allows a user to filter what’s included in the history; the possible options are either unset, ignoredups, ignorespace, and ignoreboth. ignoredups will mean repeated commands are only placed in the history once.

ignorespace will ignore commands preceded by a space, useful if you don’t want a command to show up in history. Compare the two lines below:

man ls will show up in history, whereas the man cd will not. ignoreboth will let you ignore both duplicates and space-prepended commands.

HISTIGNORE will tell bash to not add certain commands to the history; for example, HISTIGNORE='ls:cd:history' will prevent all ls, cd and checks of the history from showing up. Wildcards are also accepted.

HISTTIMEFORMAT can be used to specify a timestamp per command; HISTTIMEFORMAT="%F %T " will display the full date and time (in YYYY-MM-DD HH:mm:SS format). The trailing space must be present or there will be no space between the command and the timestamp in the history display: 2038-01-19 03:14:07echo 'Like this!'

Most experienced Linux users know about the history command, but the above may be helpful to newer users.

Photo by Dario Veronesi on Unsplash

Leave a Reply

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