Foxables Open ZSHRC - Your New Enhanced DevOps Workflow
We’ve produced an auto updating .zshrc file with cool intuitive commands and aliases designed to enhance your DevOps and Software Engineering Workflows, it’s completely free to use, easy as pie to install, and will continue to be maintained. Designed by a Software Architect for the open source world
What is a .zshrc File?
ZSH is a popular shell wraper for posix/unix based operating systems such as Mac OSX, Ubuntu, and Linux. It provides customisability to one’s shell environment enabling and facilitating visual shell extensions. The .zshrc file was introduced to provide a location whereby one could house all of their ZSH customisations such as; aliases and functions, and configuration settings for ZSH.
Why use a .zshrc File?
The power of aliases and custom functions allows you to reduce the overall complexity of your CLI workflows. By leveraging aliases to power long command names or command chains, or custom functions to handle more complex steps, you can quickly and easily reduce the complexity of your CLI Workflow saving you hours of wasted time each month.
How do I use .zshrc?
I spend most of my day in a shell environment running on Mac OSX for regular day-to-day operations and development, or in Ubuntu / AmazonLinux 2 for remote server management.
Simplifying SSH
Different environments I connect to might use different key pairs or different usernames... So I have a shell function called c
, this is short for connectToSSH
the command syntax is c <ip/hostname> user privateKey
. When I do not provide a value for user, my default user is set to ec2-user
and for privateKey, when not set my default will be ~/.ssh/id_rsa.pem
.
This allows me to run the command c 10.0.1.19
to SSH directly into an AWS EC2 instance with the IP Address 10.0.1.19
with the user ec2-user
and the private key ~/.ssh/id_rsa.pem
by executing the transposed command; ssh -i ~/.ssh/id_rsa.pem ec2-user@10.0.1.19
on port 22.
I could create a subnet to key map, perform a scan of the file and automatically use the correctly maped private key based on the IP I’m trying to connect to if I wish, but most of the time I do not need to change the value for user or privateKey.
In addition to this, we can test common usernames if the one we provide doesn’t work, that allows us to automatically fall-back onto the correct username for the host we are trying to connect to.
Finally, if your ~/.ssh/config
file contains a key to IP value for the host you’re connecting to our c
command will automatically use this key.
Simplifying Git
When working with git source control, my command flow tends to look something like this;
gs && gco master && gip && gco -b feature/branch && gsp
This command chain performs the following actions;
- Git Stash
- Git Checkout to the master trunking branch.
- Git Pull the latest changes from origin.
- Git checkout to the new feature/branch.
- Git stash pop.
Or in human language;
- Hold all current uncommitted changes.
- Switch to the master branch.
- Get the latest changes for the master branch.
- Create a new branch called feature/branch
- Release and apply the most recently held uncommitted changes and remove the holding record.
This might seem arbitrary, why not just use the commands themselves? Ok, sure, here’s the commands;
git stash && git checkout master && git pull origin master && git checkout -b feature/branch && git stash pop
The full chain of commands is almost double the amount of typing required to do literally the exact same thing... Now I know I know, don’t be lazy right?
Well, let’s apply the multiplier affect to this. 🥹
In any given day, I’m running these command chains upwards of 30 times. That means by using the short command chain, I’m saving 1,620 letters from being typed repeatedly. Multiply this by how many days in a year (I do source code work every day of the week), by using short chain commands I’m saving a staggering 591,300 superfluous characters from being typed. This translates to a tangibly considerable increase to time efficiency and reduction of wastage.
Aliases are extremely powerful tools for productivity, create functions for complex aliases (I could condense the entire chain to gits new master feature/branch
which would execute the entire command chain in sequence using new
as the keyword for which chain to execute, master
denoting the source trunking branch, and feature/branch
as the expected branch to create.)
Without further adieu, I give you a snapshot of the current version of the Foxables Open .zshrc file. 😁
#FOXABLES
# If you come from bash you might have to change your $PATH.
ME=$(whoami)
# export PATH=$HOME/bin:/usr/local/bin:$PATH
export GPG_TTY=$(tty)
export ZSH="/Users/$ME/.oh-my-zsh"
# Set name of the theme to load --- if set to "random", it will
# load a random theme each time oh-my-zsh is loaded, in which case,
# to know which specific one was loaded, run: echo $RANDOM_THEME
# See https://github.com/robbyrussell/oh-my-zsh/wiki/Themes
ZSH_THEME="robbyrussell"
ENABLE_CORRECTION="true"
COMPLETION_WAITING_DOTS="true"
CMD_TIMER_COLOR="magenta"
CMD_TIMER="true"
DEFAULT_SSH_USER="root"
DEFAULT_SSH_KEY="~/.ssh/id_rsa"
plugins=(git rails ruby gem emoji encode64 git-extras)
source $ZSH/oh-my-zsh.sh
#############################################
# Aliases
#############################################
# General
alias 7zip="~/Scripts/7zz"
alias hist="history -i"
# IaC
alias terraform="~/Applications/terraform"
alias tfp="~/Applications/terraform plan"
alias tfi="~/Applications/terraform init"
alias tfa="~/Applications/terraform apply"
alias tfd="~/Applications/terraform destroy"
# SVC
alias ga="git add"
alias gc="git commit -s"
alias gp="git push"
alias gs="git stash"
alias gsp="git stash pop"
alias gip="git pull"
alias gco="git checkout"
alias gfo="git fetch origin"
alias gsync="git pull origin/master"
alias gitfucked="git rm -rf . --cached"
#############################################
# Functions
#############################################
function gits() {
if [[ ! -z "$1" ]] && [[ ! -z "$2" ]] && [[ -z "$3" ]];
then
if [[ "$1" == "delete" ]] || [[ "$1" == "d" ]];
then
git branch -D "$2" && git push origin -d "$2"
elif [[ "$1" == "tag" ]] || [[ "$1" == "t" ]];
then
git tag "$2" && git push origin "$2"
elif [[ "$1" == "switch" ]] || [[ "$1" == "s" ]];
then
gco "$2" && gip -f
fi
elif [[ ! -z "$1" ]] && [[ ! -z "$2" ]] && [[ ! -z "$3" ]];
then
if [[ "$1" == "new" ]] || [[ "$1" == "n" ]];
then
gs && gco "$2" && gip && gco -b "$3" && gsp
fi
fi
}
function checkForOpenZSHRCUpdate() {
local FOXABLES_PATH=$(head -n 1 "$HOME/.foxables-zshrc.path")
local FOXABLES_UPDATED=$(tail -n 1 "$HOME/.foxables-zshrc.path")
local NOW=$(date +%s)
local EXPIRE=$(expr $FOXABLES_UPDATED + 604800)
if [[ $NOW -lt $EXPIRE ]];
then
return
fi
stat=$(git -C "$FOXABLES_PATH" fetch origin 2>&1)
if [[ ! -z "$stat" ]] && [[ ! "$stat" =~ "fatal" ]] && [[ ! "$stat" =~ "not found" ]];
then
read -p "A new update for Foxables Open-ZSHRC is available. Would you like to update? [y/N] " -n 1 -r
if [[ $REPLY =~ ^[Yy]$ ]];
then
git -C "$FOXABLES_PATH" pull origin master
echo "Updated! Please run 'source ~/.zshrc' again."
else
echo "$FOXABLES_PATH" > "$HOME/.foxables-zshrc.path"
echo "$NOW" >> "$HOME/.foxables-zshrc.path"
fi
fi
}
function getCMDTimerMagnitudeModifier() {
if [[ "$CMD_TIMER_MAGNITUDE" == "ms" ]];
then
# Milisecond, or 1 thousandth of a second.
echo 1000000
return
elif [[ "$CMD_TIMER_MAGNITUDE" == "us" ]] || [[ "$CMD_TIMER_MAGNITUDE" == "µs" ]];
then
# Microsecond, or 1 millionth of a second.
echo 1000
return
fi
# Default is Nanosecond, or 1 billionth of a second.
echo 1
}
function systime() {
local time=$(date $@)
if [[ "${time: -1}" == "N" ]];
then
local gtime=$(gdate $@ 2>&1)
if [[ ! "$gtime" =~ "not found" ]];
then
echo "$gtime"
return
else
# Mac OS X, if gdate is not installed you can't get nanoseconds.
echo "${time:0:-1}000000000"
return
fi
fi
echo "$time"
}
function formatFromNS() {
local delta=$1
# Days
p1=$(expr $delta / 1000000000 / 60 / 60 / 24)
# Hours
p2=$(expr $delta / 1000000000 / 60 / 60 % 24)
# Minutes
p3=$(expr $delta / 1000000000 / 60 % 60 % 24)
# Seconds
p4=$(expr $delta % 10000000000 / 1000000000)
# Miliseconds
p5=$(expr $delta % 1000000000 / 1000 / 1000 % 1000)
# Microseconds
p6=$(expr $delta % 1000000000 / 1000 % 1000)
# Nanoseconds
p7=$(expr $delta % 1000000000 % 1000)
opt=""
count=0
vals=($p1 $p2 $p3 $p4 $p5 $p6 $p7)
for i in "${vals[@]}"
do
if [[ $i -gt 0 ]];
then
if [[ -z "$opt" ]];
then
opt="$i"
else
opt="$opt $i"
fi
if [[ $count -eq 0 ]];
then
opt="${opt}d"
elif [[ $count -eq 1 ]];
then
opt="${opt}h"
elif [[ $count -eq 2 ]];
then
opt="${opt}m"
elif [[ $count -eq 3 ]];
then
opt="${opt}s"
elif [[ $count -eq 4 ]];
then
opt="${opt}ms"
elif [[ $count -eq 5 ]];
then
opt="${opt}µs"
elif [[ $count -eq 6 ]];
then
opt="${opt}ns"
fi
fi
count=$((count+1))
done
echo "$opt"
}
function preexec() {
if [[ -z "$CMD_TIMER" ]] || [[ "$CMD_TIMER" != "true" ]];
then
return
fi
cur=$(systime +%s%0N)
if [[ "$cur" =~ "not found" ]] || [[ "${cur: -1}" == "N" ]];
then
timerStart=0
return
fi
timerStart=$cur
}
function c() {
# SSH Connections.
local USER="$DEFAULT_SSH_USER"
FALLBACK_USERS=( ec2-user ubnt ubuntu root $(whoami) )
if [[ -z "$1" ]];
then
echo "Usage: c <host> [user] [key]"
exit 1
fi
local HOST="$1"
if [[ ! -z "$2" ]];
then
USER="$2"
fi
local KEY=""
if [[ ! -z "$DEFAULT_SSH_KEY" ]] && [[ -f "$DEFAULT_SSH_KEY" ]];
then
KEY="-i '$DEFAULT_SSH_KEY'"
fi
if [[ ! -z "$3" ]] && [[ -f "$3" ]];
then
KEY="-i $3"
fi
local RES=$(ssh $USER@"$HOST" $KEY "uname -mrs")
if [[ "$RES" =~ "Permission denied" ]];
then
for i in "${FALLBACK_USERS[@]}"
do
RES=$(ssh $i@"$HOST" $KEY "uname -mrs")
if [[ ! "$RES" =~ "Permission denied" ]];
then
USER="$i"
break
fi
done
fi
ssh $USER@"$HOST" $KEY
}
function precmd() {
if [[ -z "$CMD_TIMER" ]] || [[ "$CMD_TIMER" != "true" ]];
then
if [[ ! -z "$RPROMPT" ]];
then
export RPROMPT=""
unset timerStart
fi
return
fi
if [ $timerStart ] && [ $timerStart -ne 0 ]; then
cur=$(systime +%s%0N)
delta=$(($cur-$timerStart))
elapsedPretty=$(formatFromNS $delta)
export RPROMPT="%F{$CMD_TIMER_COLOR}${elapsedPretty} %{$reset_color%}"
unset timerStart
else
export RPROMPT="%F{$CMD_TIMER_COLOR}%{$reset_color%}"
fi
}
# Disable mouse accelleration on mac.
defaults write .GlobalPreferences com.apple.mouse.scaling -1
# NVM
export NVM_DIR="$HOME/.nvm"
[ -s "/usr/local/opt/nvm/nvm.sh" ] && . "/usr/local/opt/nvm/nvm.sh" # This loads nvm
[ -s "/usr/local/opt/nvm/etc/bash_completion" ] && . "/usr/local/opt/nvm/etc/bash_completion" # This loads nvm bash_completion
checkForOpenZSHRCUpdate
Source: Foxables Open .ZSHRC Raw File
How to Install?
Run the command curl -s https://raw.githubusercontent.com/Foxables/Open-zshrc/master/install.sh > install.sh && bash install.sh && rm -f install.sh && source ~/.zshrc