Most developers end up creating some sort of dotfiles repo to contain configuration files for their *nix-like machines (macOS, Linux, etc). Rather than just setting up every machine you access in an ad-hoc way, you can create a repo to keep the same environment for your terminal everywhere.
There's a lot of starting points out there that you could clone from. If you know git
, my advice would be to follow how to manage them with git
—this guide lets you use a special dotfiles
command.
My dotfiles are pretty boring, but I think there's a few parts that make mine special. Let's talk through them. I use bash
, the default in most places.
- Layout—what calls what and how things are run
- Platform Help—distinguish macOS and Linux
- Helpers—take a look inside my scripts
Layout
My layout is pretty simple. The .bash_profile
file immediately runs .bashrc
, so there's no difference in how you log in (the two files being different is a big source of confusion for newbies—so just merge them! 🤣).
One file that I've used for years is .bash_functions
(originally written by a friend back in ~2009). It provides a few helpers that make dealing with paths "safe". Here's a simple example—both pathprepend
and ssource
check that the path or file exists before using it:
#!/bin/bash
source "${HOME}/.bash_functions" # first line of .bash_profile
# adds to $PATH if the directory exists
pathprepend "/opt/local/sbin"
pathprepend "/opt/local/bin"
pathprepend "${HOME}/.local/bin"
# runs contents of .bash_local if it exists (not checked in, for
# custom changes on each machine)
ssource "${HOME}/.bash_local"
A Note On SSH
🚨 While I do check in my id_rsa.pub
file to every machine—this is the public, sharable part of your identity—I don't include id_rsa
in my dotfiles repo. I keep it only on machines I have physical access to, such as my laptop or a server in my house.
This is important. Your id_rsa
(or id_dsa
?) is private and even if it has a password, is going to be cracked if you accidentally upload it somewhere public.
Platform Help
At the top of my .bashrc
, I set a handy variable:
IS_MAC=""
UNAME=$(uname)
if [ "${UNAME}" == "Darwin" ]; then
IS_MAC="yes"
fi
I switch between macOS (which is really BSD and has older versions of things) and Linux, so this helps make a choice if things work differently, as it does for the params to ls
:
if [ $IS_MAC ]; then
alias ls='ls -lGho' # macOS doesn't support `--color=auto`, needs `-G`
else
alias ls='ls -lh --color=auto' # on Linux, `-G` means "no groups"?!
fi
Helpers
I've got a few scripts inside my ~/.local/bin
folder. Some of which I use almost daily. 📜❗#️⃣
Image Compression
I have two scripts—crush and pcrush—which compress a single PNG image, or compress many in parallel. I never remember the arguments to run the tools pngcrush
or zopflipng
(better), but it's always worth shrinking your images before you upload them (gotta go fast!).
I built pcrush
so I could also take advantage of multiple CPUs—turns out both the tools above run on a single CPU only, but if I have 100s of images, I want to crush them fast. I can make my CPUs do this:
Git Status
I have a script called gstate
which outputs a number of things based on the current Git repository. It includes branches, normal status, any stashed changes, and known divergence from upstream (i.e., the remote repo you've mirrored from).
It's handy and honestly burned into my muscle memory forever now. 💪
If you're curious, check it out here.
That's All!
I hope today's short view into my environment has been interesting! Got your own handy scripts you can't live without? Let me know! 🗣️💬
(This Blog-A-Day post goes out to my partner: holding a screaming baby while I write.)
6 👋
Top comments (6)
Do you mind sharing how you alias gstate since it's a script not a function...?
I just put the
gstate
file inside my$PATH
. I personally have a folder~/.local/bin
where this stuff lives.So...
alias gstate='bash ~/.local/bin/gstate.sh'
?
Well, if
~/.local/bin/
is in your$PATH
(if you're on Windows I'm not sure what this would look like), then you can just type "gstate.sh", or just remove the extension and type "gstate". There's no need for the alias in this case.Ooo gotcha.
Fantastic. Thank you! I like your gstate script output. :)