My name is Jean-Michel and I am a committed engineer at Per Angusta. Here is my point of view about using shortened words to describe complex intentions.
I am used to challenge the benefits of aliases in a Shell environment with my peers. I rarely hear mastered reasons but rather a pretended gain of efficiency. I personally chose to unset them all and keep being explicit with my machine.
The Shell environment
A shell is a command line interpreter for Unix-like operating systems. A place where developers (users) get control of their machine.
It has wide capabilities (depending on the OS and the version of the distribution) such as browsing directories, managing files, running scripts and installing dependencies. Its usage is a must-known for all developers. Like knives for cooks and saws for carpenters, it shapes the main toolkit for developers.
That’s why best programming training programs always start with Unix learning and practising sessions. In the best case they invite students to create their own Shell program to deeper understand what’s going on behind the scene.
Once the learning step is reached, a developer is much more autonomous in its daily issues and he starts not to depend on each others. His machine stays forever his only one working environment (until coding with LEGOs is made possible!) and mastering it is a must-have skill. That’s the purpose of a command line interpreter.
Are aliases a standard practice over the world?
They are to an extent, but their usage is not. Like Web and API protocols/frameworks, the way they work is common but there is no guarantee it is implemented the same way.
An alias is a string to be substituted for a word when it is used as the first argument of a command. It is usually a shorter word than what it is supposed to be substituted for, and is commonly composed of the first letters of the command and its first arguments. For instance:
# set an alias for staging files (git add) using patch option
alias gapa="git add --patch"
Now user can type “gapa” instead of the original command, and it’s now pretty easy to understand the first benefit of aliases: less typing, quicker control of the machine!
Aliases are set at the user session level in a Shell when the profile is loaded (for example on Bash from file “~/.bashrc”). It is then clearly identified as a User setup not related to the environment. That’s why there is no guarantee that an other user, including one on the same machine, decides that “gapa” means something else, for instance:
# set an alias for granting all permissions to all
alias gapa="chmod 777"
OF COURSE DON’T! 😱
However in this case, user decides not to use the first letters of the command and its first argument (that would have resulted in “c7”), but the ones from its human meaning, which make more sense to him because he doesn’t care about versioning files with Git but is an Access Control List manager.
Not a good approach for abstract
I can hear from my peers that aliases are one of the large set of programming abstracts: objects, methods, variables, and so on, including DRY principle (“Don’t repeat yourself”). However, the common usage of aliases sounds more like short-linking, as if you would create shortcuts on your Desktop folder to quicker access your favourites.
To me, a justified approach of abstract would be to use them as a human readable substitute for technical commands, for instances:
# deploying current branch on staging remote server
alias x-deploy-staging="git push staging $(git rev-parse --abbrev-ref HEAD):master"# archiving directory recursively
alias x-archive-directory="tar -zcvf"
In this case, user decides to abstract its common technical commands into human readable links. A prefix “x-” allows to differentiate when typing custom commands in favour of builtins and binaries. Now it is not only shortcuts for repeatable commands but it actually becomes an abstract tool.
Explicit over implicit
The more explicit a code or a library is, the easiest it is used and maintained. That’s one of the main principle developers apply: choosing appropriated variable, method and class names, especially when they work on a product that is supposed to be maintained by others.
Every developer has experienced at least once in his life (if not once a day) a peer challenging the naming of a variable after a code review. For example, given a model named “ThirdPartyClient” and a code that iterates on each of its records:
ThirdPartyClient.all.each do |tpc|
As a matter of fact at Per Angusta, a code reviewer would invite the requester to rename “tpc” by “third_party_client”. Wouldn’t you? No one would invite the opposite by asking to type less characters to gain efficiency. The readability always comes first.
For the same reason and when available, I personally prefer to use the longer version of builtins or binaries’ options. When I am running commands against an “application”, I choose to use “ — app” over “-a”. It makes more sense to me and that’s how I would write it in a Shell script before asking for a script review to my peers.
Let’s go further with the famous “git push” command, which is commonly used without any arguments because it perfectly fallbacks to defaults. When my intention is to push my work from my current branch onto its remote counterpart, I am explicitly typing the following command:
# telling exactly on which server, what to push in which branch
git push origin HEAD:feature-branch
- The remote: origin is the default remote, until it is configured another way
- The source: HEAD is the current ref, which is by default the last commit of the branch until you checkout a different one
- The destination: feature-branch is the default, until the remote one is named differently than the local branch
This way, before pushing my work I am asking myself what I exactly want my machine to do for me, giving myself more chances to not do mistakes. It invites me to ensure I know what remote, source and destination are in my current context.
Thus, the explicit version of a command is the only one I expect to find in a documentation (like articles, posts or wiki pages). Why losing those benefits while controlling my machine? I get the control of it while documenting my intention, and my Shell history is tracking it.
Let your peers know what you are really doing
When you’re riding a bike on a road and you reach a crossroad, you probably know what to do: tell the environment what your intention is. As a matter of fact, you’re aware of your own intention and your local machine (the bike) doesn’t care about it because it is controlled by you. So, why to explain your intention?
Of course you want to prevent the other users of the road from hitting you, even if your intention seems obvious. More generally you would try to make things happen in a smooth way and try to minimise the doubt. So what about applying this purpose to your Shell environment: your teammates would probably be more comfortable if you told them what your intention exactly was before running command lines in public.
It is relevant with the history: browsing a Shell session history is smoother when command lines are explicit, especially in case of a mistake analysis. As a rider, you would be more comfortable to remind a driver that you told him you would turn on the right before he hit you.
When you are working with peers with different skills level and setup, using aliases is disturbing and inefficient at all. Beginners won’t follow you and you probably will pass more time to retrieve what your aliased command actually does rather than typing its original. That is similar circumstance as if you had to explain what the variable “tpc” is whereas you could have directly named it “third_party_client”.
Efficiency gain is not obvious
Aliases are nothing more than embedded Shell scripts, except they are stored in the user session instead of script files. It can help you running repeated operations without typing them again and again. That’s why it is, and must be, considered as a good manner to gain efficiency and doing less mistakes. It is especially the case when the substituted commands require a lot of obfuscated options like “tar -zcsv”.
But, assuming you are working in a given environment (with tools and workflows in place), if you, or your team, want to gain efficiency in a Shell environment, my opinion is that you should better first ensure to:
- Ask yourself if you’re really controlling the purpose of your personal set of aliases, especially when they come from external tools (like Oh My ZSH!).
- Ask yourself if your peers can understand the rules you’ve setup in your own session, their purpose and their impact.
- Ask yourself if you would better try to setup common guidelines instead of standing apart. Bring your tools to the team and ensure every one adopt them and is trained for. For example: share a versioned and documented set of aliases or scripts through a Git repository.
- Being conscious of the impacts an obscure command line can have, starting by yourself, like issues with history analysis or pedagogical purposes while peering. It does not only apply to aliases.
- Being conscious that a Shell environment is not a programming interface. You need to know more than ever what you are actually doing and what your context is. Killing processes afterward with “Ctrl+C” has no guarantee to be reversible, whereas coding in a versioned code base is.
- Not to ask for this blog post’s author if aliases have more benefits than issues until they are implemented as a team workflow and become actual standard 😜
Interested in joining an enthusiastic engineering team?
We are recruiting talented people! Checkout our open positions here: