The Pinky Finger Habits Of Experienced Sysadmins

Over my career as a Systems Administrator, I have acquired some productive habits when I’m working on the command line that I have picked up from sysadmins more experienced than myself.

The two here both involve using your pinky fingers as they are the [ENTER] and [TAB] keys.

Hit the enter key between every command

This habit is very simple, just hit the [ENTER] key a few times between entering every command. Rather than explain why take a look at the following two terminal sessions of the same commands being entered along with their output:

First, without hitting [ENTER]:

root@server:~# apt-get update
Hit:1 http://mirror.memset.com/ubuntu xenial InRelease
Get:2 http://mirror.memset.com/ubuntu xenial-updates InRelease [102 kB]
Get:3 http://mirror.memset.com/ubuntu xenial-security InRelease [102 kB]
Fetched 204 kB in 0s (433 kB/s)
Reading package lists... Done
root@server:~# apt-get upgrade
Reading package lists... Done
Building dependency tree
Reading state information... Done
Calculating upgrade... Done
The following packages have been kept back:
  libgl1-mesa-dri sysstat
0 upgraded, 0 newly installed, 0 to remove and 2 not upgraded.
root@server:~# apt-get install openvpn
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following packages were automatically installed and are no longer required:
  apache2-bin apache2-data apache2-utils libapr1 libaprutil1 libaprutil1-dbd-sqlite3 libaprutil1-ldap libgd3 libjbig0
  libjpeg-turbo8 libjpeg8 liblua5.1-0 libtiff5 libvpx3 libxslt1.1 nginx-common nginx-core
Use 'apt autoremove' to remove them.
Suggested packages:
  easy-rsa
The following NEW packages will be installed:
  openvpn
0 upgraded, 1 newly installed, 0 to remove and 2 not upgraded.
Need to get 0 B/421 kB of archives.
After this operation, 1026 kB of additional disk space will be used.
Preconfiguring packages ...
Selecting previously unselected package openvpn.
(Reading database ... 22196 files and directories currently installed.)
Preparing to unpack .../openvpn_2.3.10-1ubuntu2.1_amd64.deb ...
Unpacking openvpn (2.3.10-1ubuntu2.1) ...
Processing triggers for libc-bin (2.23-0ubuntu9) ...
Processing triggers for systemd (229-4ubuntu21) ...
Processing triggers for ureadahead (0.100.0-19) ...
Processing triggers for man-db (2.7.5-1) ...
Setting up openvpn (2.3.10-1ubuntu2.1) ...
Processing triggers for libc-bin (2.23-0ubuntu9) ...
root@server:~# cd /etc/openvpn/
root@server:/etc/openvpn# ls
update-resolv-conf

Second, hitting [ENTER] between commands:

root@server:~#
root@server:~#
root@server:~# apt-get update
Hit:1 http://mirror.memset.com/ubuntu xenial InRelease
Get:2 http://mirror.memset.com/ubuntu xenial-updates InRelease [102 kB]
Get:3 http://mirror.memset.com/ubuntu xenial-security InRelease [102 kB]
Fetched 204 kB in 0s (433 kB/s)
Reading package lists... Done
root@server:~#
root@server:~#
root@server:~#
root@server:~# apt-get upgrade
Reading package lists... Done
Building dependency tree
Reading state information... Done
Calculating upgrade... Done
The following packages have been kept back:
  libgl1-mesa-dri sysstat
0 upgraded, 0 newly installed, 0 to remove and 2 not upgraded.
root@server:~#
root@server:~#
root@server:~#
root@server:~# apt-get install openvpn
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following packages were automatically installed and are no longer required:
  apache2-bin apache2-data apache2-utils libapr1 libaprutil1 libaprutil1-dbd-sqlite3 libaprutil1-ldap libgd3 libjbig0
  libjpeg-turbo8 libjpeg8 liblua5.1-0 libtiff5 libvpx3 libxslt1.1 nginx-common nginx-core
Use 'apt autoremove' to remove them.
Suggested packages:
  easy-rsa
The following NEW packages will be installed:
  openvpn
0 upgraded, 1 newly installed, 0 to remove and 2 not upgraded.
Need to get 0 B/421 kB of archives.
After this operation, 1026 kB of additional disk space will be used.
Preconfiguring packages ...
Selecting previously unselected package openvpn.
(Reading database ... 22196 files and directories currently installed.)
Preparing to unpack .../openvpn_2.3.10-1ubuntu2.1_amd64.deb ...
Unpacking openvpn (2.3.10-1ubuntu2.1) ...
Processing triggers for libc-bin (2.23-0ubuntu9) ...
Processing triggers for systemd (229-4ubuntu21) ...
Processing triggers for ureadahead (0.100.0-19) ...
Processing triggers for man-db (2.7.5-1) ...
Setting up openvpn (2.3.10-1ubuntu2.1) ...
Processing triggers for libc-bin (2.23-0ubuntu9) ...
root@server:~#
root@server:~#
root@server:~# cd /etc/openvpn/
root@server:/etc/openvpn#
root@server:/etc/openvpn#
root@server:/etc/openvpn#
root@server:/etc/openvpn# ls
update-resolv-conf

It should be pretty obvious that separating the commands with blank lines makes reading back over what you’ve just done much, much easier. For the same reason, never use the clear command at the bottom of your terminal page, just get used to working at the bottom of your terminal.

Having a history of not just the commands but their output and error messages is an invaluable store of information that you will refer back to frequently.

Once you start hitting enter you will do it compulsively and won’t notice that your little finger is bouncing on the enter key whilst you work.

Use Bash Complete For All The Things

Bash complete (commonly referred to as “tab-complete”) is a function in Bash that will attempt to complete a command, path, file name or command option that is currently semi-entered.

Use it for everything, everywhere, all the time as Bash complete is the single biggest time saver on the command line. Not only does it speed up your workflow by cutting down the amount of typing it also avoids typos in paths and file names.

The following examples assume that you have the bash-completion package installed.

Here are the most common Bash complete uses:

Path completion

Every Linux sysadmin has heard of and uses tab complete but most admins starting out don’t use it nearly as much as they should. If I were to judge a commands usefulness by the number of times I use it (apart from Enter, see above) then tab complete is the outright winner. Typing out paths goes from:

c d / v a r / w w w / m a g e n t o

to

c d / v [TAB] w [TAB] m [TAB]

The common locations e.g. /etc/, /home/, /var/log, become muscle memory making navigation very rapid.

Remember, if single [TAB] doesn’t bring up the right path immediately, hit [TAB] again to see all the directories that match, then add a letter or two more, and hit tab again. In the following example there are two directories; /var/www/magento and /var/www/magellen, in order to cd into /var/www/magento the following is done:

root@server:~# cd /v[TAB] /w[TAB] /m[TAB] [TAB]

This will complete to the point where the two directories differ e.g.:

root@server:~# cd /var/www/mage

Now, hit [TAB] twice, so see all the matching directories, then enter the first character of the one you want i.e. n, hit [TAB] again to complete the path and enter to complete the command. This looks like the following:

root@server:~# cd /var/www/m[TAB]
root@server:~# cd /var/www/mage[TAB][TAB]
magellen/ magento/
root@server:~# cd /var/www/magen[TAB]
root@server:~# cd /var/www/magento/[ENTER]
root@server:/var/www/magento#

File name completion

This is simply an extension of the path completion. Bash complete will complete any file name that you start entering. Using Bash completion here will reduce typos to zero and speed up entering file names.

Bonus, if there is only a single file or directory in a directory Bash complete will select that file name or directory name without any initial characters being entered.

Command and command option completion

Bash complete will check auto-complete any command you start by checking your $PATH for all matching commands. You only need to enter enough of the command for Bash complete to finish it for you. If you don’t remember the entire command just hit [TAB] twice to see all the matching commands.

In addition, for many of the most common commands, Bash complete will also complete options for you.

For example, entering the command systemctl reload apache2.service employing Bash complete becomes:

root@server:~# systemc[TAB] rel[TAB] apa[TAB]

As with the common paths, common commands will become muscle memory making them extremely fast to enter.