If you spend time working in the terminal, whether for work or leisure, a lot of the commands you type often have a dependency on other recent commands, might be repetitive actions, or be very similar to other commands previously run. Gaining mastery over your shell history is a great way to be more productive in the terminal.
I’m going to share some tips which improve my speed while using the shell to perform common sysadmin tasks, or file manipulation.
Get a better history
New users to the Linux command-line might first grasp the
history command, or
perhaps the up/down arrows to
show recent commands. They might have also learned to use tab-complete
extensively, maybe a little too much. They may even use the
ctrl-r command to
search the history. This offers some degree of productivity, but we can do
better than this.
Depending on your operating system, you may have some of the following
suggestions applied by default, whether as a global setting or applied at a
local level in the
.bashrc folder in your home directory. To apply new
settings, I suggest you make a backup of this file, and open it in your
favourite editor. After saving, you can load the new settings with
~/.bashrc, or logout/login again.
1. Use HISTIGNORE to remove pointless commands from history
Some bash commands are used to provide some moment-in-time information but
don’t change your environment, and aren’t useful in your history. Adding the
HISTIGNORE variable to your
.bashrc file allows you to choose which
standalone commands to drop from your history. Here’s an example:
Add to this list or remove from it as you see fit - some people use the
an alias of
ls -alF. A frequent user might want to stop this from appearing
in their history too.
As a bonus, if you don’t want certain sensitive commands appearing in your history, for example if you are specifying a password or API key on the command line, then you can use the following option to make sure that any command beginning with a space does not appear in the history file:
This isn’t the only option: for example, the
ignoredups option will only
store one copy of a command if the consecutive command is identical.
2. Don’t lose important history
histappend option, you will find that if you open multiple
concurrent shell sessions, then only entries from the last exiting shell is
saved (history is saved in memory and written to the history file upon exit).
Another annoyance can be that you may share a root shell with other
administrators on a server, and important history gets lost because the history
file is too small. I usually set a history file size of at least 10,000 entries
to avoid losing an audit trail, or useful commands.
shopt -s histappend export HISTSIZE=10000
3. Recalling commands effectively
Now that you have a more streamlined command history, we can do more that
up/down arrow to select previous commands.
!! command recalls the previous line. For example.
$ pwd /etc $ !! pwd /etc
This can be used as part of a command, so
sudo !! will run the previous
command with sudo privileges. You can cause a lot of damage by blindly running
sudo with recalled commands, so you should add
:p on the end of the command
to recall but not actually run the command. It will then appear as the last
command in your history which can be accessed with a single press of the
Also you can run a command from your history by putting a
! in front of the
line number provided by the history command. Due to the higher likelihood of
mistyping a number here, I tend to add the
:p to show me the command but not
run it. Then I can do up arrow to show the command in order to check it and run
it with a carriage return
$ rm -r temp/ $ mkdir temp $ touch temp/test $ !! touch temp/test $ history | tail -4 179 rm -r temp/ 180 mkdir temp 181 touch temp/test 182 touch temp/test 183 history | tail -5 $ !179:p rm -r temp $ !180 touch temp/test
You can also call the last used occurrence of a command with a
! in front.
!ping will run the last command you ran beginning with
This is a powerful time saver, which I use all the time (e.g.
!vim will open
the vim editor with the last file I opened - handy when performing a few
consecutive edits on a file) but you need to be sure of what you
are doing when using riskier commands. Again, you can add a
:p to show
expansions without actually executing them.
If you are a really risk-averse person, you can skip the use of
:p and add
shopt -s histverify to your
.bashrc file and every command expanded with
! will be recalled on the current line but will wait for you to press enter.
4. Using parameters from the previous line with !$ and !*
One of my favourite efficiency tips is use of
!* to refer to parts
of the previous command (as opposed to
!! for the whole command).
!$ will expand to the last parameter of the last command, which can
save you a lot of typing or copy-pasting. For example, rename a file, then edit
$ mv list.txt items.txt $ vim !$ vim items.txt $ cp !$ shopping.txt cp items.txt shopping.txt
!$ expands to the value of the last parameter of the previous line, i.e
!$ expands to
!* will expand the value of all of the parameters on the previous line
(i.e. the whole line except the first word). Not quite as commonly used as
which I use constantly but handy nonetheless. In this example, we remove some
log files and then create some empty versions of the same file:
$ rm /var/log/httpd/access.log /var/log/httpd/error.log $ touch !* touch /var/log/httpd/access.log /var/log/httpd/error.log
5. Replace a matching word from the previous line with ^
This is another big time-saver which a use a lot, particularly when you are
manipulating files with long path names. The
^ symbol allows you to repeat
the previous command after switching a matching word. For example:
$ rm /var/log/httpd/error.log $ ^error^access rm /var/log/httpd/access.log
6. Use readline for partial history search
This isn’t strictly a BASHism, but it will change your life! Adding certain
~/.inputrc will allow you to do things like this:
ssh <up arrow>and cycle through your previous ssh sessions
git <up arrow>and cycle through previous git commands
cp -r <up arrow>and cycle through previous recursive copies you did - notice that it doesn’t have to be just one word
It really makes a difference - you will find yourself typing
history | grep
ssh, or searching history aimlessly with arrow keys a whole lot less!
To enable this functionality, create a file called
.inputrc in your home
directory, containing the following lines, then restart your bash session
# include the system-wide settings $include /etc/inputrc # enable partial history search "\e[A": history-search-backward "\e[B": history-search-forward
If you aren’t getting left/right arrow functionality, and ctrl-left/right isn’t working to skip words, you might need to add:
# Use arrow keys to move character left/right "\e[C": forward-char "\e[D": backward-char # Use Ctrl and Arrow keys to move along words "\e[1;3C": forward-word "\e[1;3D": backward-word
One gotcha is that if you are expecting to use regular up/down arrow to browse your full history, then you need to have a blank line before doing this - not even any spaces entered!
Let me know how you get on by pinging me on Mastodon.