Be more productive with Bash aliases

Aliases are one of the most interesting features provided by a Bash shell, and probably the last to be regularly adopted. Usually, they are intended as a way to create shortcuts to execute the most used commands followed by the options that are not assumed by default from the command itself. However, there is a more appealing way to write them that boost our productivity when executing either frequent or infrequent tasks.

The default aliases

Every distribution provides a set of aliases by default, the most known are ll, which stands for ls -l and la, which stands for ls -la.

Being pretty neat they are so widely accepted that are often confounded as commands.

Among the pre-configured aliases, we can find also: dir, md, rd, cd... This set is freely inspired by the Windows Prompt commands, probably there to help those coming from that operative system to find a Bash shell more familiar.

Looking around for more aliases examples there is not much variety, everyone tends to repeat a similar pattern, using a short amount of characters and system-related use cases.

A different point of view

In my opinion, there is a reason why aliases are not much used, or not widely adopted as they should.

The beginners tend to avoid them as much as they can because of afraid to forget the so shadowed command(s) executed.

The most experienced users instead prefer these cryptic alias names with a very short number of characters, cool to see but easy to forget, especially if seldom used.

Of course in the different stages of my learning process I made the same mistakes and after years of Linux terminal usage, the most used aliases were for me still ll and la.

In brief, my alias list was useless and mostly left unused.

Readability first

Although looks cool to have monosyllabic that execute very long instructions, how on earth would be easy to remember that o (this is a built-in alias) stands for less? There is no relationship at all between the two words.

Now imagine creating an alias for git push -u origin main like gpom and gpo for the same operation on a not mentioned branch, they look quite easy to remember, especially if Git is part of our daily routine.

What about if in the middle of our job we take a long pause from Git to use CVS and then go back to it after months?

Rely on a strong memory is not, at least for me, a valid answer and I am pretty sure to forget these couple of alias in less then a month.

An alternative is to use a long name (no worries, the Tab key completion still works for aliases), and a better strategy to organize them.

Easy to find vs easy to remember

I don’t want aliases easy to remember, not at a first instance at least, what I want is to have a list of aliases easy to find!

Again, if I am using git and I am writing aliases to remember a particular action, why don’t make all of them start with its complete command name?

Would be way easier to find all the aliases related to git if they all start with either git_ or, for those like me fond about Ruby and its Object Oriented Programming language, using the dot notation as git.action.

Being the dot . character in my keyboard layout easy to access (the underscore _ is accessed through Shift + -) this last solution works great for me, plus when I want to use the original command I just put a space after the last character (i.e. the t of git) of the command itself.

Otherwise, I just append a dot . symbol, and with the Tab key I can print my alias list for to the git command.

This is the approach I regularly use to memorize all the useful options for compilers and related toolchains every time I have to learn a new programming language, but it works also for more complex command-line applications.

That way I can focus more on the language itself, or the goal that a command+parameters combo achieves, instead of trying to remember the single options.

Also, the more common system commands having many options might take advantage of that technique, let’s see a couple of self-explanatory aliases about find:

alias find.empty.dirs='find . -type d -empty'
alias find.empty.files='find . -type f -empty'

In that case another dot . introduced a common namespace before calling the action: the empty status of files or dirs to look for.

How to organize namespaces and actions is strictly personal and also a solution like that has perfectly sense:

alias find.dirs.empty='find . -type d -empty'
alias find.files.empty='find . -type f -empty'

In this last example, we would talk about a specification for the empty word appended, in both cases, the goal has been accomplished: aliased once, easy to find always!

Group of aliases

The just seen dot notation is very useful to create aliases and

  • separate a command from the action;
  • eventually, group them for a particular problem using a namespace.

The commands we have seen till now were perfectly bound to their final result.

Moving away from computer programming there are a plethora of small commands that have not much sense to be aliased under the command name itself, that because they have a mean only when used together with other commands and the result is not much tied to any particular command name used.

Let’s think about an alias that prints the version number of our beloved distro, this is the chain of commands:

$ cat /etc/os-release | grep VERSION= | cut -f 2 -d =

How to group it in a way that’s easy to remember? Following the aforementioned examples, we should choose a name among cat, grep, cut.

Honestly, who would associate one of these commands to the operative system version query?

The solution might be to group this kind of aliases for the goal achieved, in this particular case it might be the info provided:

alias info.os.version="cat /etc/os-release | grep VERSION= | cut -f 2 -d '=' "
alias info.os.name="cat /etc/os-release | grep ^NAME= | cut -f 2 -d '=' "
alias info.os.prettyname="cat /etc/os-release | grep PRETTY_NAME= | cut -f 2 -d '=' "

We might create other aliases to provide further info about configurations, devices, diagnostic, …, as shown below:

alias info.GPU='sudo lspci -v | grep -i "VGA controller"'

alias info.ip='curl http://icanhazip.com'
alias info.ip.lan='ip address | grep inet | grep -E "wlan|eth" | sed "s@^ \+@@"  | cut -f 2 -d " " '

alias info.kernel='uname -mrs'

Grouping for goal didn’t break the promise to keep aliases easy to find, and the connection between alias name and the final result is as strong as before.

Subgroups of commands

We can use this approach also to rename those commands not easy to remember at all, at least at the beginning.

For example, to print the mount point of a certain file or folder, there is the stat command able to do that:

$ stat -c %m 

Unfortunately, this is among of those command names rarely used and difficult to remember: when we think to get info from a file we name the file command just after ls.

Being stat easier to associate to the file group we might create a subgroup under file and collect all the stat actions we want to alias:

alias file.stat.mountpoint='stat -c %m'
alias file.stat.userid='stat -c %u'
alias file.stat.username='stat -c %U'
alias file.stat.blocks='stat -c %b'

Nesting commands still help to keep a well-arranged list, easy to browse, and without losing the reference to the original command. Of course we might totally remove any stat mention in the alias name, but in my opinion keeping this reference might also be helpful to remember these less-used commands.

Let’s make it short

As we have seen the long dot notation has its advantage over the short version, printing that list at the screen or on a paper sheet we get a small cheat list of all the discovered commands, a valid compendium during our learning activity.

However, some of these commands might be very frequently used, and introducing a short version of them now wouldn’t be a mistake.

What I strongly suggest is to keep anyway the longer version, and use a short acronym to alias that alias.

This is an example from my list:

alias zypper.info='zypper --no-refresh if'
alias zypper.install='sudo zypper in'
alias zypper.orphaned='zypper --no-refresh pa --orphaned'
alias zypper.remove='sudo zypper rm --clean-deps'
alias zypper.search='zypper --no-refresh se'
alias zypper.unneeded='zypper --no-refresh pa --unneeded'
alias zypper.update='sudo zypper up'

alias zif='zypper.if'
alias zin='zypper.install'
alias zor='zypper.orphaned'
alias zrm='zypper.remove'
alias zse='zypper.search'
alias zun='zypper.unneeded'
alias zup='zypper.update'

Although it sounds repetitive and pedantic I prefer this way to don’t break the listing by collection triggered with the Tab key, and still have shortcuts for almost daily tasks, as a plus, every time some adjustment should be made, it would happen once.

Some tips

As a bonus here below a couple of aliases to create our cheat list keeping separated the long versions from the short:

alias alias.long='alias | grep alias[^.=]*='
alias alias.short='alias | grep \\.[^=]*='

To keep all your aliases separated from the rest of the configurations, let say in the ~/.aliases file, just append the following line within the .bashrc file:

source "$HOME/.aliases"

Final thoughts

Using the method discussed above made me rediscover the usefulness of Bash aliases, saving me a lot of time from googling for the same command again and again.

Every time I find an useful set of commands that can be aliased, I just append another line in my list, it might be useful someday, and now also easy to re-discover.


Creative Commons License This work is licensed under a Creative Commons Attribution-NoCommercial-ShareAlike 4.0 International License


Leave a Comment