How to Extend Your Shell with Custom Commands

Alexey Anufriev
Celonis Engineering
3 min readMar 31, 2020

--

Originally posted at celonis.com

During development, we at Celonis type a lot in our IDEs. The good thing about this process is that IDE supports us here a lot. Things like shortcuts, live templates, and other features help us get more code with less effort. You do not need to rename class across all places — just hit a shortcut instead. Or, if you need a public constant of a String type in your class, just type psfs and hit Tab. Lastly, if you do not know how to do this or that, just hit Shift key two times and ask IDEA.

Besides IDEs, we also type a lot in the shell (whatever you use, but I prefer zsh). I believe it would be cool to have a similar level of convenience there, as well. There are plenty of existing extensions for the shell that can make your life easier, like kubectx, or fubectl for K8s, ect. However, sometimes it is not that easy to find an extension that does exactly you want, and gives you exactly what you need daily, because it may be super-specific. To overcome this, you have the possibility of extending your shell with custom commands.

The shell can easily be extended with custom commands using two approaches: aliases and functions.

Alias

It is kind of a shortcut for another command. Let’s say to check the content of the directory with all hidden files, with human-readable size, in a list view, you would need to run something like this: ls -laGh. It is not that long, but you need to remember all the options.

Or, the easier way is to simply add something like alias ll=’ls -laGh’ to your ~/.zshrc (or ~/.bashrc) and just be able to type ll, to see the following:

Function

One problem that cannot be solved with aliases is that they cannot accept arguments. But sometimes you need to run parameterized command and it would be nice to make a shortcut for it as well. And the solution here is — functions!

For example, from time to time I wonder why I cannot run this or that docker image when it fails with “port is already in use“. And here I need to run another command (I prefer lsof) to figure out what is going on there and who took my port. And those commands are usually quite verbose and may have lots of options or be heavily stacked with a pipe operator.

To implement an alias for a command that accepts input arguments you can define a function inside your ~/.zshrc (or ~/.bashrc) and call it by name passing some values.

Here is my function from the example above (figuring out ports usage):

#port check 
function port() {
lsof -i -P -n | grep :$1
}

And here is how it can be used:

This is how easy the shell can be extended.

Happy coding!

--

--