A shell is your most open channel for communicating with the kernel of your operating system. It is a ‘shell’ around your kernel that takes the commands that you write to it and performs actions based on the commands you give. It is best to get familiar with it and make it your best friend.

There is actually not that much that you have to do to make a really powerful and modern looking shell on your brand new Unix machine.

There are a couple of different shells available that you can choose from and each has a different interface you can use to talk and communicate with it. Most often the default shell is Bash.

If you wish however, you can change your shell. Some good choices include Zsh, Fish or Elvish.

The download instructions for each of these shells can be found on their websites alongside the documentation and tutorials for how to effectively use them. In this guide however I will go over what my shell looks like and how I often communicate with it.

I use Zsh as my shell of choice. However both Zsh and Bash are pretty boring when you first try them. I mean it is 2017. Why does your shell have to look like this:

It doesn’t have to. And the awesome thing is that you can change how your shell looks and what your shell can do by downloading various plugins that other people have created and shared. GitHub is an awesome place to find such plugins amongst other things.

Dotfiles

But before we start customizing our shell, let’s create a home for it on our system. Most people create a folder called ‘.dotfiles’ in their home directory. The name ’dotfiles’ is chosen because it will contain various hidden configuration files that on Unix start with a dot.

If you are using Zsh. The file that Zsh reads when you first boot it up is named .zshrc and it is located in your home directory together with most other configuration files. If you want to move this .zshrc file to your newly created home in ’dotfiles’, you can’t. If you do just move it, then Zsh will try to search for the .zshrc file in the home directory but will not find anything so no custom configs you wrote will get run.

You can avoid this by creating a symlink from dotfiles to the home directory. A symlink is just a shortcut, like a portal from getting from point A to B on your system. For example, in my case I have the folder ‘.dotfiles’ and inside it, I have folder zsh which has a file named zshrc. You can then create a symlink to the .zshrc file using this command:

ln -s ~/.dotfiles/zsh/zshrc ~/.zshrc

The syntax for creating symbolic links looks like this:

In my case the original file actually lies in dotfiles and the symlink I have created in my home directory points to it. You have to make sure however to write the correct file for the symlink as only the full correct name will be seen by zsh.

You can now actually share your 🏡 with other people if you wish. Most people share their configuration files and put them on GitHub. To do this, simply initialise your dotfiles folder with git init , create a repository on GitHub, I named mine dotfiles, and then just push to it.

Dotbot

The reason why people put their configuration files inside this .dotfiles folder and put it under version control is that it is now really easy to transfer your entire’s macOS/linux configuration to other machines. However having to create these symbolic for all these different config files every time is painful. To avoid this pain I use Dotbot.

It is best to read through the README that Dotbot has to understand how you can use it. In essence, Dotbot allows you to create a install script written that will create all the necessary symbolic links for you as well as run any other commands you want it to run. So you can just clone some dotfiles directory and run ./install script and everything is setup in seconds. No pain. Here is how my install script looks like for reference.

Extending Zsh

Now that we have zshrc, we can hack on it and download plugins to make it even more awesome. Before we do that, we still have one more thing left we need to do. We need a package manager.

Downloading and using a packager manager is easy on macOS. Nix is an amazing choice and it is both easy to install by running this command in your terminal:

curl https://nixos.org/nix/install | sh

And is easy to use. You can search through different packages you can install here and install the ones you need with:

nix-env -f ‘<nixpkgs>’ -iA <pkg-name> .

For example running this:

nix-env -f ‘<nixpkgs>’ -iA neovim

Will install Neovim editor for you to use on your system. It is however best to get familiar with the Nix package manager by reading the manual. It is a powerful tool that is worth learning.

Now that we have our package manager, we can install our plugin manager for Zsh with it. I use and recommend Antibody for this. I found oh my zsh to be too bloated and prezto which is better, felt like a black box and although its ‘sane defaults’ are nice, I wanted to set my own defaults and have complete control over my shell experience.

Assuming you have installed zsh, you can install antibody by running:

nix-env -f ‘<nixpkgs>’ -iA antibody

You can take a look at Antibody docs for more information on how it works and how to work with it but the way I use it is this.

For my use, I created a file called plugins.txt inside zsh dir of my dotfiles. I then created a Zsh function that looks like this:

updatezsh() {

antibody bundle <~/.dotfiles/zsh/plugins.txt >~/.zsh_plugins.sh

antibody update

}

Which when I run, I download all the plugins that I put inside plugins.txt file . You can see Zsh plugins I use here.

Running install.sh then will install all these plugins to a file which you can then run from your zsh. To do this, open zshrc in your dotfiles and put source ~/.zsh_plugins.sh inside it. To activate the changes either source your zshrc from your shell source ~/.dotfiles/zsh/zshrc or start a new shell.

Awesome. 🎊

Now your shell should look like this:

It also has really awesome syntax highlighting inspired by fish shell.

To further personalize your shell, you can do many different things. But one thing that I love doing is setting aliases for long or even short commands. An alias is essentially a shortcut to a command. So for example, I have an alias for opening my vim terminal.

alias e='nvim'

I also have an alias for opening my zshrc from vim:

alias ez='nvim ~/.dotfiles/zsh/zshrc'

And many many more. I even structure them to different files and then source each file from zshrc. I have my own semantic way of naming my aliases too. For example my two most often used aliases are

alias a='ls'

alias d='cd'

I can then create aliases like this:

alias ds='cd ~/src'

alias di='cd ~/ideas

alias dl='cd ~/learn'

And so on. It is immensely fast to move around my file system now. I also made a custom alfred workflow to quickly go to different folders on my system. Here is the workflow and here is how it looks in action:

Workflow in action

Now you are ready to explore the world of open source and see what other people have created and see what you like and integrate that into your workflow.

I list my favorite commands I use here and my own dotfiles can be found here.

See what you like and play around with it. If you didn’t find anything that solves the problem you have, you can always create your own program, and share it with the world.