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:
- I’m a heavy user of
git
,docker
andmake
. - I like automation and containers.
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
e94423e8d2e7
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
e94423e8d2e7
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
0eb093472f56aa26c85b91449d733a40ca94d8bf09cfbf496a2d6632da53bf19
fc1800580212a5468506298d21add15700b904ac3067fd5001e6cb171c6a341e
da7aaa55bcce6d1bedd09157075105576eadb8c6ea05cf268068951a064e4c06
07706331a5072436dcd4bcc842547925227f912301d37027126305eaf9abe67b
7d15e9f9bced2a4beb600617141ee31515730e6a4c3e8524530754ce88e05c06
$ alias dclean='dka; drms'
$ dclean
7d15e9f9bced
07706331a507
da7aaa55bcce
fc1800580212
0eb093472f56
7d15e9f9bced
07706331a507
da7aaa55bcce
fc1800580212
0eb093472f56
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"
else
MESSAGE=$(curl -sq https://status.github.com/api/last-message.json | jq .body)
echo Last message from github is: ${MESSAGE}
fi
}
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:
- I’m a heavy git user.
- It provides auto completion for most of the commands I use.
- I like the PowerLine font and ability to set up cute emojis on my terminal ?
- It makes it very easy for me to visualize if I have made some changes in my current working directory.
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
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:
- Use aliases whenever it is possible to do so.
- Use bash functions with positional commands for more advanced functionality
- Install the ZSH shell and set it up with useful plugins to your tasks to maximize output.
If you liked this blog post, click on recommend below or follow me on Twitter