Terminal tricks to boost productivity

 Escape tedious commands

There’s always those horrible, tedious, uncomfortable to type commands that you type in every single day at work at least once. Something like

git pull or git fetch

Can be shortened to a much shorter command like gp or gf. Here’s where alias comes to the rescue. But before that, we need yo identify what long commands we type in more often to make the most out of our aliases.

 Identifying long commands

To see the commands that we use the most we can call the history command and with the help of superuser, make sense of our daily input.

history | awk '{CMD[$2]++;count++;}END { for (a in CMD)print CMD[a] " " CMD[a]/count*100 "% " a;}' | grep -v "./" | column -c3 -s " " -t | sort -nr | nl |  head -n10

The output of that command was the following when I typed it in my computer:

     1  2009  20.092%    git
     2  1058  10.5811%   docker
     3  802   8.0208%    make
     4  407   4.07041%   ll
     5  383   3.83038%   cd
     6  350   3.50035%   kubectl
     7  178   1.78018%   ls
     8  151   1.51015%   rm
     9  151   1.51015%   aws
    10  148   1.48015%   crafter

If I do the same changing the $2 for $3 then I get the next positional command:

history | awk '{CMD[$3]++;count++;}END { for (a in CMD)print CMD[a] " " CMD[a]/count*100 "% " a;}' | grep -v "./" | column -c3 -s " " -t | sort -nr | nl |  head -n13
     1  694  6.94069%
     2  650  6.50065%   commit
     3  408  4.08041%   status
     4  311  3.11031%   ps
     5  262  2.62026%   ssh
     6  209  2.09021%   logs
     7  203  2.0302%    get
     8  175  1.75018%   |
     9  172  1.72017%   add
    10  171  1.71017%   checkout

From issuing those two commands, we’re able to extract a few conclusions:

So, for now on, we will focus on 2 out of the 3 most commonly used; git and docker.

 Creating alias

Next up, create the actual aliases, but before that let’s decide on an appropriate name for the resulting command that we’ll create. If we take a look to the most used command we’ll want to create something meaningful to be able to identify what that alias does, but also make it short to improve our performance.

For example the combination of git commit -m <message>. I do this 5 to 10 times a day on the least git intensive day of them all.

$ alias gcm='git commit -m'
$ gcm "First commit" .
$ git push

That will create our alias and set it up for our current session, also the amount of characters required to form the command went from 13 to 3, pretty big improvement I would say.

Now, let’s also poweruser our Docker command and create some aliases to it. There’s one thing that I do a lot these days, that being a temporary Alpine Linux containers to test stuff. After which, the stopped container is not needed for any reason, unless that’s gathering dust and occupying disk space. The command itself is a bit awkward to type in: docker run --rm -ti alpine sh. That grants me an interactive container to play with, which is how I create most of my Docker images.

$ alias alpine-shell='docker run --rm -ti alpine sh'
$ alpine-shell
/ #

We have another massive character reduction right there. What about killing all the running containers, and removing them? I’m also going to create an alias for that docker kill all functionality

$ alias dka='docker kill $(docker ps -q)'
$ dka

I also like to have all the containers that are stopped removed from my machine, furthermore, we don’t need the volumes associated with the removed containers laying around doing absolutely nothing, remove those too. I’ll call it docker remove stopped

$ alias drms='docker rm -v $(docker ps -aqf "status=exited")'
$ drms

Now, I love automation, and because of that I want to concatenate my 2 commands into 1 single easy to type command: dclean which stands for docker clean. To test this command out, we’re going to generate a few containers to kill and remove:

$ for c in $(seq 5); do docker run -d alpine sleep 100; done
$ alias dclean='dka; drms'
$ dclean

I’m already seeing few more minutes added to my day by just adding 5 silly aliases, but useful nonetheless.

Did you think we were finished? No way, we’re just getting started

 Going the extra mile with functions

At this point you should have a clear understanding of what aliases can do, but not what they cannot do, imagine that you want to create an alias that concatenates two commands, but needs a part in the middle of the command to be dynamic.

git commit -m "<message" && git push

Unfortunately alias cannot make that happen for you but, luckily enough I know just the right approach to use, did I say functions? I think I already did.

$ function gcmp() {
  git commit -m "${*}" && git push
$ gcmp Remove comment

You need a passphrase to unlock the secret key for
user: "Marc Lopez <marc5.12@outlook.com>"
4096-bit RSA key, ID F543AAF5, created 2016-05-18

[master 3bee85a] Remove comment
 1 file changed, 1 deletion(-)
Counting objects: 7, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (6/6), done.
Writing objects: 100% (7/7), 1.38 KiB | 0 bytes/s, done.
Total 7 (delta 3), reused 0 (delta 0)
To git@github.com:marclop/docker-alpine-images.git
   eba5d6d..13420ee  master -> master

For those unfamiliar with ${*}, it takes everything typed after gcmp and passes it to the function, so it’ll fill fhe message part.

Also, we can improve readability of commands aliases and instead of concatenating 2 commands inside an alias, the same can be done with a function and let me say this, it looks much better.

function dclean() {
  docker kill $(docker ps -q)
  docker rm -v $(docker ps -aqf "status=exited")

Another function I have available in my terminal is to check GitHub status, if systems are operating normally then it just tells me that all the system’s are in great shape, if not, it will print the last github message regarding their current incident. Be aware that the script uses jq. Installing it on Mac OS X is as easy as typing brew install jq

function github_status() {
  local STATUS=$(curl -sq https://status.github.com/api/status.json | jq .status | tr -d '"')

  if [[ ${STATUS} == "good" ]]; then
    echo "All systems are in good shape"
    MESSAGE=$(curl -sq https://status.github.com/api/last-message.json | jq .body)
    echo Last message from github is: ${MESSAGE}

To finalize this chapter, remember to save all this functions in the appropriate .bash_profile / .bashrc / .zshrc inside your home directory to have them load up when starting up the terminal. As a rule I always have separate files for aliases or functions and source that file inside my shell, which is zsh when I’m using my laptop.

 Install and Set up zsh

You might ask, why the hell should I switch my default shell from bash to zsh? It’s quite easy to answer the question from my side:

Installing it is as easy as typing

$ sh -c "$(curl -fsSL https://raw.github.com/robbyrussell/oh-my-zsh/master/tools/install.sh)"

That will set it up for you, if you want more information on how to set up the fonts and all the other stuff, here’s the link. Here’s an example of a auto competition with a git command and a git directory with non-committed staged changes

git status.png

 Wrapping up

As you can see, following a simple set of instructions can boost your productivity a lot by cutting the type in time for most annoying commands by at least half. To close the article here are some useful bullet points:

If you liked this blog post, click on recommend below or follow me on Twitter


Now read this

SmartOS overview

Why Smartos? There are many hypervisors on the market, from VMware’s ESXi to Citrix XenServer, but they’re not a very good match for a standalone Hypervisor because they are architectured and built to be deployed in a... Continue →