Always read and understand anything you copy into your terminal.
I’ll document the SSH scripts I regularly use here. I suggest creating a .functions
file in your root directory, adding whichever functions you find interesting to it, and finally appending source .functions
to your .bash_profile
to initialize the functions on startup. You can also add these colors to the top of your .functions
file since a couple functions use colors.
bold = $( tput bold )
underline = $( tput smul )
reset = $( tput sgr0 )
red = $( tput setaf 1 )
green = $( tput setaf 2 )
blue = $( tput setaf 4 )
cdls
cd
and ls
at the same time. Useful if you’re like me and always want to see what files are available when navigating the terminal.
function cdls () {
builtin cd " $@ " && ls
}
mkvenv
Make a new Python virtual environment and activate it.
function mkvenv () {
python3 -m venv venv
source venv/bin/activate
pip install --upgrade pip
}
mkgit
Create a new Git repository locally and push it to GitHub. Requires having the GitHub CLI installed (run brew install gh
to install with Homebrew).
#!/bin/bash
# Style variables
bold = $( tput bold )
blue = $( tput setaf 4 )
red = $( tput setaf 1 )
green = $( tput setaf 2 )
reset = $( tput sgr0 )
# Function to check if a command exists
command_exists () {
command -v " $1 " & > /dev/null
}
# Function to print a step message
print_step () {
echo "${ bold }${ blue }=> $1 ${ reset }"
}
# Function to print success message
print_success () {
echo "${ bold }${ green } $1 ${ reset }"
}
# Function to print error message
print_error () {
echo "${ bold }${ red } $1 ${ reset }"
}
# Function to initialize the git repository
initialize_git () {
if ! command_exists git ; then
print_error "Git could not be found. Please install it before proceeding."
return 1
fi
print_step "Initializing the git repository..."
git init -b main
git add .
git commit -m "Initial commit"
print_success "Git repository initialized successfully."
# Setup Python project if applicable
if [[ " $is_python_project " == "yes" ]]; then
setup_python_project
fi
}
# Function to setup a Python project
setup_python_project () {
print_step "Setting up the Python project environment..."
# Create .gitignore
echo "venv/" >> .gitignore
# Create the virtual environment and activate it
python3 -m venv venv
source venv/bin/activate
print_success "Python virtual environment created and activated."
# Create .pre-commit-config.yaml with the provided configuration
cat << EOF > .pre-commit-config.yaml
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- repo: https://github.com/bwhmather/ssort
rev: v0.11.6
hooks:
- id: ssort
- repo: https://github.com/pycqa/isort
rev: 5.12.0
hooks:
- id: isort
args: ["--profile", "black", "--filter-files"]
- repo: https://github.com/psf/black
rev: 23.3.0
hooks:
- id: black
args: ["--line-length", "120"]
EOF
# Install pre-commit hooks
pre-commit install
print_success "Pre-commit hooks installed."
}
# Function to create a GitHub repository
create_github_repo () {
if ! command_exists gh ; then
print_error "GitHub CLI could not be found. Please install it before proceeding."
return 1
fi
print_step "Creating the GitHub repository..."
if gh repo create " $directory " --source=. --remote=upstream --push --${ visibility } ; then
print_success "Created the repo $directory on GitHub!"
else
print_error "Failed to create the GitHub repo. Please check your network connection and try again."
return 1
fi
}
# Main function to make a git repository
mkgit () {
# Ask for the directory name
echo -n "${ bold }${ blue }Please enter the directory name: ${ reset }"
read directory
if test -d " $directory " ; then
echo "${ bold }${ red }Error: Folder already exists.${ reset }"
return 1
fi
# Make sure this is running in the Documents folder
if ! [[ "$( pwd )" =~ ~ /Documents. * $ ]]; then
echo "${ bold }${ red }Error: Please navigate to the documents folder before running this script.${ reset }"
return 1
fi
# Create a local directory and enter it
mkdir " $directory " && cd " $directory "
# Ask for repository visibility
echo -n "${ bold }${ blue }Should the repository be public or private? (public/private): ${ reset }"
read visibility
while [[ " $visibility " != "public" && " $visibility " != "private" ]]; do
echo "${ bold }${ red }Invalid input. Please enter either 'public' or 'private': ${ reset }"
read visibility
done
# Ask for README contents
echo -n "${ bold }${ blue }What would you like the README to say?: ${ reset }"
read readme_content
echo " $readme_content " > README.md
# Default .gitignore contents
echo ".vscode/" >> .gitignore
# Check if it's a Python project
echo -n "${ bold }${ blue }Is this a Python project? (yes/no): ${ reset }"
read is_python_project
# Ask for vscode settings
echo -n "${ bold }${ blue }Would you like to add a .vscode/settings.json file? (yes/no): ${ reset }"
read vscode_answer
if [[ " $vscode_answer " == "yes" ]]; then
mkdir -p ".vscode" && touch ".vscode/settings.json"
fi
# Initialize local git repo
initialize_git
# Prepare for linking local repo to GitHub
create_github_repo
}
sshgo
This is handy if you SSH into servers a lot from your terminal. It gives you a quick dropdown of your servers and uses the usernames and hostnames you provided ahead of time.
function sshgo () {
# Define the colors and styles using ANSI escape codes
local RED = "\033[31m"
local GREEN = "\033[32m"
local YELLOW = "\033[33m"
local CYAN = "\033[36m"
local BOLD = "\033[1m"
local RESET = "\033[0m"
# Define your SSH accounts as indexed arrays
local labels = ( "1" "2" "3" ) # Labels for each account
local descriptions = ( "GPU 1" "GPU 2" "Digital Ocean" ) # Descriptions for each account
local commands = ( "user1@gpu1" "user2@gpu2" "root@123.123.123.123" ) # SSH commands
# Print a pretty list of your SSH accounts
echo -e "${ GREEN }${ BOLD }SSH Accounts:${ RESET }"
echo -e "${ CYAN }-------------${ RESET }"
for i in "${ ! labels [ @ ]}" ; do
echo -e "[${ YELLOW }${ BOLD }${ labels [ $i ]}${ RESET }] ${ CYAN }${ descriptions [ $i ]}${ RESET }"
done
echo -e "${ CYAN }-------------${ RESET }"
# Prompt the user to select an account
read -p "Enter the number corresponding to the account you want to SSH into: " selection
# Check if the entered number is valid
if [[ ! " ${ labels [ @ ]} " =~ " ${ selection } " ]]; then
echo -e "${ RED }Invalid selection. Please try again.${ RESET }"
return 1
fi
# Find the index of the selected label
local index
for i in "${ ! labels [ @ ]}" ; do
if [[ "${ labels [ $i ]}" == "${ selection }" ]]; then
index = " $i "
break
fi
done
# SSH into the selected account
echo -e "${ GREEN }Connecting to ${ descriptions [ $index ]}...${ RESET }"
ssh ${commands[$index]}
}
refresh_dots
Updates a dotfiles repository with relevant dotfiles. Will need to change file paths to match your machine.
function refresh_dots () {
# Go to root
cd ~
# Refresh Brewfile
rm Brewfile
HOMEBREW_NO_AUTO_UPDATE = 1 brew bundle dump
# Copy main dotfiles
cp .bash_prompt .bash_profile .bashrc .aliases .exports .functions .gitconfig .gitignore_global .git-completion.bash .hushlogin .inputrc .vimrc Brewfile .tmux.conf Documents/code/dotfiles
# VSCode
cp ~/Library/Application \ Support/Code/User/{settings.json,keybindings.json} Documents/code/dotfiles/vscode
cp -R ~/Library/Application \ Support/Code/User/snippets Documents/code/dotfiles/vscode
cp ~/.vscode/extensions/extensions.json Documents/code/dotfiles/vscode
# Go to dotfiles folder
cd ~/Documents/code/dotfiles
}
execution_time
A handy add-on to Bash shells showing you how long each command takes to run. Great way to start gaining intuition on the relative amounts of time functions take. May need to run brew install coreutils
. Idea credit to Swyx .
preexec () {
timer = $( gdate +%s.%N )
}
precmd () {
if [ -n " $timer " ]; then
now = $( gdate +%s.%N )
elapsed = $( echo " $now - $timer " | bc )
timer_show = $( printf "%.2f" $elapsed)
echo "Execution time: ${ timer_show }s"
unset timer
fi
}