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

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 to c (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'