Learn Docker With My Newest Course

Dive into Docker takes you from "What is Docker?" to confidently applying Docker to your own projects. It's packed with best practices and examples. Start Learning Docker →

Moving a Bunch of Shell Alias Functions into Their Own Script Files


Aliases and shell functions serve a similar purpose, but they don't need to be kept in the same file.

Quick Jump: Demo Video

For the longest time I’ve kept both aliases and shell functions in the same ~/.config/zsh/.aliases file. There was nothing wrong with that but now that I’m starting to add more and more functions this file is starting to get a little unwieldy.

From a human scannability perspective, it would be nice to have a bunch of 1 line aliases defined in 1 spot but larger multi-line functions really deserve their own file.

In either case the user experience is the same. For example I have a shell function which I can call in my terminal by running start-recording which I run before recording videos. As its own individual script I still run start-recording to invoke it.

Splitting out these functions into dedicated script files is also more user friendly for anyone wanting to use my dotfiles. Now you can pick and choose which scripts you want instead of taking my entire .aliases file.

From a script maintainability perspective the dedicated script is a huge win too. Now you can fuzzy find a script to open and work on it in isolation. Every time you edit the script you don’t need to source ~/.config/zsh/.aliases to reload it. That’s a quality of life improvement.

Lastly, I’ve kept around an .aliases.local file which isn’t commit to version control because it contains commands very specific to my own set up, such as custom directory paths for personal projects.

You can still do the above with this new model. You could make a ~/.local/bin/private directory and put this on your system path, then place all local or private scripts there. That’s a safe directory name to use because private is a built-in shell command so you wouldn’t want to have a script named private anyways.

All of these changes are up in my dotfiles, here’s the single commit. The video below is a live demo where I moved everything over while going over my thought process.

Demo Video


  • 1:18 – A few advantages to breaking them out into scripts
  • 4:38 – Setting a bin path and handling local or private scripts
  • 6:01 – Handling the idea of a private bin directory
  • 9:48 – vdiff
  • 13:00 – dtags
  • 15:16 – weather
  • 16:59 – gcb (git clean branches)
  • 17:56 – change-terminal-font
  • 18:50 – Optimizing our workflow
  • 19:22 – mkscript
  • 19:53 – stop-recording
  • 20:18 – start-recording
  • 21:25 – Making shellcheck happy
  • 23:14 – Symlinking and verifying a few scripts work


Do you prefer shell functions or dedicated script files? Let me know below.

Never Miss a Tip, Trick or Tutorial

Like you, I'm super protective of my inbox, so don't worry about getting spammed. You can expect a few emails per month (at most), and you can 1-click unsubscribe at any time. See what else you'll get too.