Code or Die Welcome to my kitchen

Yak shaving tips, Infosec, Astronomy, Gardening

This is my blog. Proud guardian of three cats and two dogs, I currently reside in San Antonio, Texas.

I'm interested in gardening, astronomy, infosec among other pursuits. About this site.

Past and current projects. You can also browse the blog archive if you like.

Message of the Day: Party on dudes!

How I Learned To Stop Worrying And Love The Default Terminal App

As a recovering champion yak shaver I used to obsessively customize the heck out of every single environment, operating system, or program I touched. In my wiser years I have to shake my head at such time-intensive exercises.

In my experience the less customization the better. As a dev you should be able to blow away any program, environment, or operating system at the drop of a hat and be functional in minimal time.

In my opinion it is no use being precious about extensive customizations if it takes one a long time to re-create.

Oh, you have a 15-pane tmux with customized run commands? Cool. Your IDE settings.json stretches from here to Timbuktu? Nice!

I really hope you don’t have to reinstall that program/env/OS or, heaven-forbid, have it suddenly become unavailable on your machine due to org security or compliance reasons.

I now prefer to use default programs and commands to get up and running as soon as possible on a clean reinstall of software.

If you must customize, then save a copy of modified settings if possible on separate media or a remote repo to be able to quickly re-customize. However even this I’ve found to be a pain point.

Don’t get me started on devs that hesitate to drop dev databases and re-create from scratch, when this is exactly the purpose of dev databases. They are ephemeral and built to be blown away with regularity.

If you are not able to drop a dev DB for fear of losing info, consider a rake task or seed file to easily re-create this info.

This brings up a corrolary to this principle which is don’t alias destructive commands. Destructive in this case meaning irreversible.

I am big fan of trash the brew cask that gives the user a command to send files to system trash. However I made a huge mistake when I aliased the system’s rm to trash.

It is way too easy to slip into muscle memory in the wrong circumstances. You could one day be SSH’ed into a remote machine and forget this alias isn’t available and rm -rf <something important>. Oops, I just destroyed <something important> instead of sending it to system purgatory.

My point is yak shaving is fun until we have to reset your environment or OS. Always keep a backup, but better yet get to know and love default programs/commands. Usually the functionality you are seeking is already there, e.g. using default zsh functionality instead of the overkill that is oh-my-zsh framework.

Your future self will thank you.

Let's Use Brew Zsh

I’ve had switch default zsh to brew zsh more than once so into a blog post it goes. Luckily macOS seems to now keep system packages more up-to-date than in yesteryear.

$ which zsh
/bin/zsh

brew install zsh

$ which zsh  
/opt/homebrew/bin/zsh

Update iTerm2 or favorite term program to use /opt/homebrew/bin/zsh.

Add the brew zsh to the list of acceptable shells in /etc/shells if you plan on using ftpd.

# Add to list then run command
chsh -s /opt/homebrew/bin/zsh

Also a cargo cult relic of mine is a .zprofile file, I believe brew used to tell you to do this:

# Homebrew
eval "$(/opt/homebrew/bin/brew shellenv)"

I’m not sure this is even needed anymore but I am too afraid to remove it😭. Maybe a future post…

Let's Use Homebrew curl

While macOS supplies a fine and dandy curl binary for Terminal, let’s install an updated version managed by brew.

First let’s see what is there.

$ which curl                                                                        
/usr/bin/curl

$ curl --version                                                                           
curl 8.7.1 (x86_64-apple-darwin23.0) libcurl/8.7.1 (SecureTransport) LibreSSL/3.3.6 zlib/1.2.12 nghttp2/1.61.0
Release-Date: 2024-03-27
Protocols: dict file ftp ftps gopher gophers http https imap imaps ipfs ipns ldap ldaps mqtt pop3 pop3s rtsp smb smbs smtp smtps telnet tftp
Features: alt-svc AsynchDNS GSS-API HSTS HTTP2 HTTPS-proxy IPv6 Kerberos Largefile libz MultiSSL NTLM SPNEGO SSL threadsafe UnixSockets

Not too shabby. To be frank I’d expected worse 😂 But now let’s install curl via brew. Optionally add binary filepath to $PATH env var so brew’s curl is used instead of system’s.

From curl docs1:

$ brew install curl

$ echo 'export PATH="$(brew --prefix)/opt/curl/bin:$PATH"' >> ~/.zshrc

$ source ~/.zshrc

However if you are like me and use .zshenv for your env vars, use the following line in that file instead. (Or use ~/.zshev as target of above echo command.)

export PATH="$(brew --prefix)/opt/curl/bin:$PATH"

After reloading/sourcing terminal window, we now see this.

$ which curl                                                                 
/opt/homebrew/opt/curl/bin/curl

$ curl --version    
curl 8.13.0 (aarch64-apple-darwin23.6.0) libcurl/8.13.0 OpenSSL/3.4.1 (SecureTransport) zlib/1.2.12 brotli/1.1.0 zstd/1.5.7 AppleIDN libssh2/1.11.1 nghttp2/1.65.0 librtmp/2.3
Release-Date: 2025-04-02
Protocols: dict file ftp ftps gopher gophers http https imap imaps ipfs ipns ldap ldaps mqtt pop3 pop3s rtmp rtsp scp sftp smb smbs smtp smtps telnet tftp ws wss
Features: alt-svc AsynchDNS brotli GSS-API HSTS HTTP2 HTTPS-proxy IDN IPv6 Kerberos Largefile libz MultiSSL NTLM SPNEGO SSL threadsafe TLS-SRP UnixSockets zstd

Addendum:

I had to revert the interpolation in .zshenv as it was not working as intended. Using /opt/homebrew hard coded instead of $(brew --prefix).

¯\(ツ)