This post contains details of how I set up my shell and environment. I use Windows, Mac, and Linux on a daily basis, so I have different setups for different purposes, but I try to make them similar when I can. You can see the softwhere I use and how I customize it in the linked posts; this post will focus on setup.
Table of Contents
- Shell
- Installing Homebrew
- Installing Anaconda
- Packages
- Exports
- Aliases
- Functions
- Shell-specific
- My .zshrc
- Alias Notes
- Finding How Things Got in Environment
- Useful Git Commands
- Appendix
- Old
Shell
On Macs, I use zsh as my main shell. It’s the default shell now but older Macs will need to install it. My setup is based around zsh
.
Shell Configuration
I use Oh My Zsh to configure zsh and highly recommend it.
Development Environment
I have a particular way I set up my development environment. I store all of my aliases and environment variables other than my passwords in a ~/.profile
file. This way I can share it with a team and we can all have the same hotkeys. In ~/.profile
, I source a separate file called something like .my_credentials
, which is where all my credentials are exported from.
I source ~/.profile
from whatever shell I’m using. If I’m using Oh My Zsh, I create a file that just says source ~/.profile
and save it at ~/.oh-my-zsh/custom/profile.zsh
. I usually leave the .zshrc
file alone, but you can customize the Oh My Zsh theme if you want.
The full chain looks like this:
~/.zshrc
-> ~/.oh-my-zsh/custom/profile.zsh
-> ~/.profile
-> ~/.my_credentials
- Also
.profile
will source.bash_profile
if it exists
I put all this in a dotfiles repo so that it is under version control. I use symlinks from there to do the above.
Other Additions
Sometimes other applications will place information in your profile files. Some examples:
- brew puts something in
zprofile
- conda adds to
.zshrc
or sometimes.bash_profile
depending on how you install it.
Installing Homebrew
Homebrew is the best package manager for Mac. It installs in /usr/local
for macOS Intel and /opt/homebrew
for Apple Silicon. You can run the right location either way with this:
# Set Homebrew path and run eval
HOMEBREW_PREFIX=$(brew --prefix)
if [[ -d "${HOMEBREW_PREFIX}" ]]; then
eval "$("${HOMEBREW_PREFIX}/bin/brew" shellenv)"
fi
Installing Anaconda
- In general, I recommend installing Anaconda for all users. If you do, it will be stored in:
/opt/anaconda3/bin/conda /opt/anaconda3/condabin/conda
Packages
There are a few packages I use to improve my terminal experience.
Pygments
- Pygments, a Python syntax highlighter. It’s like
cat
with colors. I alias it toc
(as seen below).
Autojump
ZSH Syntax Highlighting
To activate the syntax highlighting, add the following at the end of your .zshrc:
source /opt/homebrew/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh
If you receive “highlighters directory not found” error message,
you may need to add the following to your .zshenv:
export ZSH_HIGHLIGHT_HIGHLIGHTERS_DIR=/opt/homebrew/share/zsh-syntax-highlighting/highlighters
Exports
export BASE="$HOME/git"
export DATA="$HOME/data"
export MODELS="$HOME/models"
export FZF_DEFAULT_OPS="--extended"
Aliases
# GENERAL ALIASES
## MOVING AROUND
alias cdh="cd $BASE"
alias please='sudo $(history -p !!)' # redo last command but with sudo
alias ff='find . -name' # find file
alias ftxt='grep -rnw . -e'
alias fpy='find . -name "*.py" | xargs grep --color'
alias grep='grep --color=auto'
alias hgrep='history | grep -v grep | grep '
alias ll='ls -GlAFh'
alias lls='ls -GlAFhS'
alias c='pygmentize -g' # like cat but with color
alias t='tail -v'
alias ckenv='printenv | grep -i' # check environmental variables
alias path='echo $PATH | tr ":" "\n"'
alias mkdir='mkdir -pv' # automatically make child directories
alias pu='popd'
alias pd='pushd'
alias c='clear'
## DATA SCIENCE
alias ip='ipython'
alias nb='jupyter notebook'
alias wgpu='watch -d -n 0.5 gpustat' # requires gpustat
alias ns='watch -d -n 0.5 $BASE/nvidia-htop.py'
alias ca='conda activate'
alias pie='pip install -e .'
## TMUX ALIASES
alias tmn='tmux new-session'
alias tmk='tmux kill-session -t'
alias tma='tmux a -t'
alias tm='tmux ls'
## GIT ALIASES
alias gs='git status'
Functions
# find text
function ft {
grep -rn . -e "$1"
}
function cheat() {
curl cht.sh/$1
}
function extract () {
if [ -f $1 ] ; then
case $1 in
*.tar.bz2) tar xjf $1 ;;
*.tar.gz) tar xzf $1 ;;
*.bz2) bunzip2 $1 ;;
*.rar) unrar e $1 ;;
*.gz) gunzip $1 ;;
*.tar) tar xf $1 ;;
*.tbz2) tar xjf $1 ;;
*.tgz) tar xzf $1 ;;
*.zip) unzip $1 ;;
*.Z) uncompress $1 ;;
*.7z) 7z x $1 ;;
*) echo "'$1' cannot be extracted via extract()" ;;
esac
else
echo "'$1' is not a valid file"
fi
}
Shell-specific
ZSH
alias rld='source ~/.zshrc' #reload profile
include () {
[[ -f "$1" ]] && source "$1"
}
# zsh syntax highlighting
include /usr/local/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh
## allow autojump
include /usr/local/etc/profile.d/autojump.sh
My .zshrc
Conda will install the initialization script for conda inside .zshrc
(for Macs). It will depend on whether you installed Anaconda or Miniconda, and on whether you installed in for a single user or for all users. If it’s installed for all users it will be somewhere like /opt/anaconda3/etc/profile.d/conda.sh
. If it’s just installed for one user it will be somewhere like /Users/$USER/opt/anaconda3/etc/profile.d/conda.sh
. The whole initialization looks like one of the following (depending on whether you use Anaconda or Miniconda):
# >>> conda initialize >>>
# !! Contents within this block are managed by 'conda init' !!
__conda_setup="$('/bin/conda' 'shell.bash' 'hook' 2> /dev/null)"
if [ $? -eq 0 ]; then
eval "$__conda_setup"
else
if [ -f "/home/jsimonelli/miniconda3/etc/profile.d/conda.sh" ]; then
. "/home/jsimonelli/miniconda3/etc/profile.d/conda.sh"
else
export PATH="/home/jsimonelli/miniconda3/bin:$PATH"
fi
fi
unset __conda_setup
# <<< conda initialize <<<
# >>> conda initialize >>>
# !! Contents within this block are managed by 'conda init' !!
__conda_setup="$('/home/julius/anaconda3/bin/conda' 'shell.bash' 'hook' 2> /dev/null)"
if [ $? -eq 0 ]; then
eval "$__conda_setup"
else
if [ -f "/home/julius/anaconda3/etc/profile.d/conda.sh" ]; then
. "/home/julius/anaconda3/etc/profile.d/conda.sh"
else
export PATH="/home/julius/anaconda3/bin:$PATH"
fi
fi
unset __conda_setup
# <<< conda initialize <<<
It’s fine to keep in there, but if you use tmux
, you might run into a problem. tmux
doesn’t always source .zshrc
. Sometimes it only sources .profile
, so conda won’t load in a tmux window. Even worse, it may pull Python from /usr/bin/python
, which will be old Python 2 (use which python
to see which Python is being used). So you might want to cut and paste the initialization over to .profile.
I have found that if I don’t include conda activate $DEFAULT_CONDA_ENVIRONMENT
in my .zshrc
, it doesn’t activate my default profile, even though I have this in my .profile
. So I leave it in .zshrc
.
Other stuff is added to .zshrc
automatically as well. Things like [ -f ~/.fzf.zsh ] && source ~/.fzf.zsh
automatically get added here. If you don’t need it for tmux
, you can leave it here. Otherwise I would recommend moving it all over to .profile
.
Alias Notes
If you make a shortcut to your code base like so:
export BASE='$HOME/git'
then if you want to use it in an alias you’ll have to use double quotes.
Instead of alias cdh=cd $BASE'
you’ll have to use alias cdh="cd $BASE"
However, if you were just doing it with $HOME
, it seems single quotes work.
Finding How Things Got in Environment
If you want to find how something got in your conda environment, you could grep it like this:
grep 'mysterious_message' ~/.bashrc ~/.bash_profile ~/.profile
Useful Git Commands
These are good to set to an alias
git log --pretty=format:'%C(yellow)%h %Cred%ad %Cblue%an%Cgreen%d %Creset%s' --date=short
Testing:
# set a fancy prompt (non-color, unless we know we "want" color)
case "$TERM" in
xterm-color|*-256color) color_prompt=yes;;
esac
Appendix
Full .profile
# General Aliases
alias rld='source ~/.zshrc' # Reload ZSH configuration
alias please='sudo $(history -p !!)' # Redo last command with sudo
alias ff='find . -name' # Find files
alias fwrd='grep -rnw . -e' # Recursive word search in files with line numbers
alias ftxt='grep -rn . -e' # Recursive text search in files with line numbers
alias fpy='find . -name "*.py" | xargs grep --color' # Find and grep Python files
alias grep='grep --color=auto' # Grep with color
alias hgrep='history | grep -v grep | grep ' # Search command history
alias psgrep='ps aux | grep -v grep | grep ' # Search processes
alias ll='ls -GlAFh' # List with details, in human-readable format
alias lls='ls -GlAFhS' # List files sorted by size
alias showpath='echo $PATH | tr ":" "\n"' # Show PATH with each directory on a new line
# GPU Monitoring (requires gpustat and/or nvidia-smi)
alias wgpu='watch -d -n 0.5 gpustat' # GPU stats (requires gpustat)
alias ns='watch -d -n 0.5 nvidia-htop.py' # Alternative GPU monitoring
# Environment Variable Check
alias ckenv='printenv | grep -i' # Search environment variables
# Enhanced cat with syntax highlighting
alias ccat='pygmentize -O style=monokai -f console256 -g'
alias c='clear' # Clear terminal screen
# PATH Viewing
alias path='echo -e ${PATH//:/\\n}' # Display each PATH entry on a new line
# Tmux Aliases
alias tmn='tmux new-session' # Start a new tmux session
alias tmk='tmux kill-session -t' # Kill a tmux session
alias tma='tmux a -t' # Attach to a tmux session
alias tm='tmux ls' # List all tmux sessions
# Python and Related
alias ip='ipython' # IPython shortcut
alias ca='conda activate' # Activate a conda environment
alias nb='jupyter notebook' # Start Jupyter Notebook
# alias pip='uv pip'
# File Navigation
alias cdh='cd ~/git' # Go to the git directory
# Git Aliases
alias gs='git status' # Show git status
# Helper Functions
function cheat() {
curl cht.sh/$1 # Fetch cheat sheet from cht.sh
}
# Extract various compressed file types
function extract() {
if [ -f "$1" ]; then
case $1 in
*.tar.bz2) tar xjf "$1" ;;
*.tar.gz) tar xzf "$1" ;;
*.bz2) bunzip2 "$1" ;;
*.rar) command -v unrar >/dev/null && unrar e "$1" || echo "Install unrar to handle .rar files" ;;
*.gz) gunzip "$1" ;;
*.tar) tar xf "$1" ;;
*.tbz2) tar xjf "$1" ;;
*.tgz) tar xzf "$1" ;;
*.zip) unzip "$1" ;;
*.Z) uncompress "$1" ;;
*.7z) command -v 7z >/dev/null && 7z x "$1" || echo "Install 7z to handle .7z files" ;;
*) echo "'$1' cannot be extracted via extract()" ;;
esac
else
echo "'$1' is not a valid file"
fi
}
# History Settings
export HISTSIZE=1000000
export HISTFILESIZE=1000000000
export HISTCONTROL=ignoredups:erasedups # No duplicate entries in history
# Source external files if they exist
include() {
[[ -f "$HOME/$1" ]] && source "$HOME/$1"
}
# Allow sublime text to be opened from command line with `subl`
export PATH="/Applications/Sublime Text.app/Contents/SharedSupport/bin:$PATH"
# Additional includes for ZSH plugins and utilities
include /usr/local/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh # ZSH syntax highlighting
#include /usr/local/etc/profile.d/autojump.sh # Location on intel Macs
include /opt/homebrew/etc/profile.d/autojump.sh # Location on Apple Silicon Macs
include .credentials # Add passwords and other credentials
Old
Exports
export HISTSIZE=1000000
export HISTFILESIZE=1000000000
export HISTCONTROL=ignoredups:erasedups # no duplicate entries
# general aliases
#redo last command but with sudo
alias psgrep='ps aux | grep -v grep | grep '
alias ccat='pygmentize -O style=monokai -f console256 -g'
alias c='pygmentize -g' # like cat but with color
alias pu='popd'
alias pd='pushd'
alias c='clear'
# See what's in your path
# Watch GPU usage
alias wgpu='watch -d -n 0.5 nvidia-smi'
alias ns='watch -d -n 0.5 $OI_BASE/core/nvidia-htop/nvidia-htop.py'
#alias wgpu='watch -d -n 0.5 gpustat' # requires gpustat
#alias ns='watch -d -n 0.5 nvidia-htop.py
# Moving around
alias cdh='cd ~/git'
# conda
alias catf='conda activate tf' # tensorflow environment
alias capt='conda activate pt' # pytorch environment
# git
alias gs='git status'