Shell
.zshrc
Gist: https://gist.github.com/ar2pi/41d1d0645d6437d7b69b6e7c64e88d8e
Snippets
#!/usr/bin/env {zsh,bash}
Get current script directory and filename
CURRENT_SCRIPT_DIR=$(dirname ${BASH_SOURCE[0]}) # Relative path
CURRENT_SCRIPT_DIR=$(cd $(dirname ${BASH_SOURCE[0]}) && pwd) # Absolute path
CURRENT_SCRIPT_FILE=$(basename ${BASH_SOURCE[0]})
Default variable value
${var:-"default"}
See POSIX spec
Bash strict mode
#!bin/bash
set -e # exit on error
set -u # error on unitialized variable
set -o pipefail # error out on pipes
# also
set -x # print out commands
See Set Builtin bash reference manual
Hash tables (associative arrays) in linux shell scripts
bash
bash v3
function key_val () {
case $1 in
"foo") echo "bar";;
"baz") echo "qux";;
*) echo "default";;
esac
}
for key in "foo" "baz"; do
echo "$key: $(key_val $key)"
done
bash v4
declare -A arr
arr=([foo]=bar [baz]=qux)
for key in ${!arr[@]}; do
echo "$key: ${arr[$key]}"
done
zsh
declare -A arr
arr=([foo]=bar [baz]=qux)
for key value in ${(kv)arr}; do
echo "$key: $value"
done
Hacky cross-shell alternative
#!/bin/bash
arr=(
"key value"
"foo bar"
)
for item in "${arr[@]}"; do
key=$(echo $item | cut -d " " -f 1)
value=$(echo $item | cut -d " " -f 2)
echo "$key: $value"
done
Parse arguments
# single argument flag
if [[ ! -z ${1+_} && ($1 = "-v" || $1 = "--verbose") ]]; then
is_verbose=1
fi
# single argument with value
if [[ ! -z ${1+_} && ($1 = "-n" || $1 = "--name") ]]; then
name=$2
fi
# multiple args, with positional support
positional_args=()
while [[ $# -gt 0 ]]; do
case $1 in
"-n"|"--name") name=$2; shift;;
"-v"|"--verbose") is_verbose=1;;
*) positional_args+=($1); shift;;
esac
shift
done
Bash command line argument parser
#!/usr/bin/env bash
#
# An over-engineered bash argument parser
# Inspired from *args and **kwargs in Python
#
# Usage:
# parse_args "$@"
#
# Examples:
# script.sh 10 20
# args: [10, 20]
# kwargs: []
# script.sh --foo bar --baz qux 10 20
# args: [10, 20]
# kwargs: [foo: bar, baz: qux]
# script.sh -x 3 -y 2 -z -- 10 20
# args: [10, 20]
# kwargs: [x: 3, y: 2, z: 1]
#
declare -a args
declare -A kwargs
function is_value () {
if [[ $(echo $1 | grep -cE "^-") = 0 ]]; then
return 0
fi
return 1
}
function parse_args () {
local arg
local value
while [[ $# -gt 0 ]]; do
if [[ $1 = "--" ]]; then
shift; continue
elif $(is_value $1); then
arg=$1
else
arg=$(echo $1 | sed -nE "s/--?(.*)/\1/p")
fi
if [[ ! -z ${2+_} ]] && $(is_value $2) && ! $(is_value $1); then
kwargs[$arg]=$2
shift
elif ! $(is_value $1); then
kwargs[$arg]=1
else
args+=($arg)
fi
shift
done
}
Load other bash files
[[ -f /path/to/script.sh ]] && . /path/to/script.sh
#!/usr/bin/env bash
#
# A simple bash script to execute all adjacent scripts
#
# Usage:
# source /path/to/all.sh
# OR
# . /path/to/all.sh
#
# Options:
# -v|--verbose: verbose output
#
function main () {
local CURRENT_SCRIPT_DIR=$(dirname ${BASH_SOURCE[0]})
local CURRENT_SCRIPT_FILE=$(basename ${BASH_SOURCE[0]})
local modules=$(ls -1 -I $CURRENT_SCRIPT_FILE $CURRENT_SCRIPT_DIR)
local is_verbose=$([[ ! -z ${1+_} && ($1 = "-v" || $1 = "--verbose") ]] && echo "1" || echo "0")
for module in $modules; do
if [[ -f $CURRENT_SCRIPT_DIR/$module ]]; then
. $CURRENT_SCRIPT_DIR/$module
if [[ $is_verbose = 1 ]]; then
echo "Loaded $CURRENT_SCRIPT_DIR/$module"
fi
fi
done
}
main "$@"
Log function
#!/usr/bin/env bash
#
# A simple bash function to output messages
#
# Usage:
# out "Hello world!"
# out warn "A warning message"
# out error "An error message"
#
function out () {
local RST="\033[0m"
local YELLOW="\033[0;33m"
local MAGENTA="\033[0;35m"
local CYAN="\033[0;36m"
local LIGHT_YELLOW="\033[0;93m"
local LIGHT_MAGENTA="\033[0;95m"
local LIGHT_CYAN="\033[0;96m"
local msg=$1
local color_1=$CYAN
local color_2=$LIGHT_CYAN
if [[ $1 == "warn" ]]; then
msg=$2
color_1=$YELLOW
color_2=$LIGHT_YELLOW
elif [[ $1 == "error" ]]; then
msg=$2
color_1=$MAGENTA
color_2=$LIGHT_MAGENTA
fi
echo -e "${color_1}❯${color_2} $msg${RST}"
}
Autoload .nvmrc
#!/usr/bin/env zsh
#
# Call `nvm use` automatically in a directory with a .nvmrc file, silently
#
# Usage:
# Add this to your ~/.zshrc
#
# Taken from https://github.com/nvm-sh/nvm#zsh
# Difference being that this one is less verbose (like pyenv or goenv)
#
autoload -U add-zsh-hook
load-nvmrc() {
local node_version="$(nvm version)"
local nvmrc_path="$(nvm_find_nvmrc)"
if [[ -n $nvmrc_path ]]; then
local nvmrc_node_version=$(nvm version $(cat ${nvmrc_path}))
if [[ $nvmrc_node_version = "N/A" ]]; then
nvm install
elif [[ $nvmrc_node_version != $node_version ]]; then
nvm use > /dev/null
fi
elif [[ $node_version != "$(nvm version default)" ]]; then
nvm use default > /dev/null
fi
}
add-zsh-hook chpwd load-nvmrc
load-nvmrc
Adblock.sh
#!/usr/bin/env bash
#
# This script will append additional entries (from http://winhelp2002.mvps.org/hosts.txt) in /etc/hosts file.
# run: "adblock"
#
# Notes:
# - A backup is created as `hosts.bk` in current working directory.
#
cp /etc/hosts hosts.bk
sudo sh -c "curl -sSL -o - http://winhelp2002.mvps.org/hosts.txt >> /etc/hosts"