extending shell with custom code

Developers: How to Extend Your Shell with Custom Commands

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 in, 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 similar level of convenience there, as well. There are plenty of existing extensions for it that can make your life easier, like kubectx, or fubectl for K8s, etc. However, sometimes it is not that easy to find an extension that does exactly what 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.


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, an even easier way is to simply add something like alias ll='ls -laGh' to your ~/.zshrc (or ~/.bashrc) and just be able to type $ ll.



One problem that cannot be solved with aliases is that they cannot accept arguments. But sometimes you need to run parametized command and 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, 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 those commands are usually quite verbose and may have lots of options or be stacked with a pipe.

To implement an alias for a command that needs an incoming 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

This is how easy the shell can be extended.

Happy coding!

Alexey Headshot
Alexey Anufriev
Principal Software Engineer, Celonis

Software development enthusiast, open-source contributor. Passionate about innovations in the IT world. Curious about security and performance. In spare time trying to tame JVM, and at work extending clouds.

Dear visitor, you're using an outdated browser. Parts of this website will not work correctly. For a better experience, update or change your browser.