Skip to content

Instantly share code, notes, and snippets.

@taeram
Last active June 3, 2019 17:20
Show Gist options
  • Save taeram/6231524 to your computer and use it in GitHub Desktop.
Save taeram/6231524 to your computer and use it in GitHub Desktop.
Handy Bash Code Snippets and functions
############################
#### Google Shell Style Guide
############################
http://google-styleguide.googlecode.com/svn/trunk/shell.xml
## Increment a variable
siteId=0
siteId=$(( siteId+1 ))
echo $siteId # 1
siteId=$(( siteId+1 ))
echo $siteId # 2
############################
#### Iterate over a thing
############################
THINGS=( foo bar bez )
for THING in ${THINGS[*]}; do
echo $THING
done
for I in {1..100}; do
echo $I
done
MAX_NUM=100
for I in $( seq 1 $MAX_NUM ); do
echo $I
done
# Iterate over a directory of files
cd /path/to/files/
for file in *.txt; do
echo $file
done
# Iterate over an array of lines with whitespace
lines="this is a line\nthis is another line"
while read -r line; do
echo $line
done <<< "$lines"
############################
#### Only allow a single instance of a script to run at a time
############################
# Original retrieved from http://stackoverflow.com/a/1985512 on 2017-03-17
LOCK_FILE=/tmp/$( md5sum "$0" | awk '{print $1}' ).lock
LOCK_FD=99
_lock() {
flock -$1 $LOCK_FD;
}
_no_more_locking() {
_lock u;
_lock xn && rm -f $LOCK_FILE;
}
lock() {
eval "exec $LOCK_FD>\"$LOCK_FILE\"";
trap _no_more_locking EXIT;
# Obtain an exclusive lock immediately or fail
_lock xn;
}
lock || exit 1
############################
#### Prevent a script from using up too many disk resources
############################
# Set IO Priority to Best Effort (2), lowest priority (7)
ionice -c2 -n7 -p$$
############################
#### Get the absolute path to the current script
############################
SCRIPT_DIR=$( dirname $(readlink -f $0) )
############################
#### Get date in sortable format
############################
DATE=$( date +"%Y-%m-%d_%H:%M:%S" )
DATE=$( date --utc +"%Y-%m-%d_%H:%M:%S" )
##
# Print coloured text
#
# @param string $1 The text type. Must be one of: success, info, warning, danger
# @param string $1 The string to echo
##
function echoc() {
BLUE='\e[0;34m'
RED='\e[0;31m'
GREEN='\e[0;32m'
YELLOW='\e[1;33m'
NORMAL='\e[0m'
if [ "$1" = "success" ]; then
echo -e "$GREEN$2$NORMAL"
elif [ "$1" = "info" ]; then
echo -e "$BLUE$2$NORMAL"
elif [ "$1" = "warning" ]; then
echo -e "$YELLOW$2$NORMAL"
elif [ "$1" = "danger" ]; then
echo -e "$RED$2$NORMAL"
fi
}
echoc "success" "Success!"
echoc "warning" "Warning: don't press the red button"
echoc "danger" "Danger: you pressed the red button!"
############################
# Print a timestamped message to the screen
#
# @param string $1 The message
############################
function log {
GREEN='\e[0;32m'
BLUE='\e[0;34m'
NORMAL='\e[0m'
echo -e "$BLUE`date '+%Y-%m-%d %H:%M:%S'`$NORMAL - $GREEN$1$NORMAL"
}
############################
# Ask a question and return the response
#
# @param string $1 The question
# @param integer $2 If not empty, don't lowercase the response
#
# @return string
############################
function ask {
if [ ! -n "$1" ]; then
log "ask() requires a question to ask"
exit 1;
fi
YELLOW='\e[1;33m'
NORMAL='\e[0m'
read -p "`echo -en "$YELLOW>>> $1 $NO_COLOR"`" ANSWER
echo $ANSWER
}
##
# Convert a string to lowercase
#
# @param string $1 The string
#
# @return string
##
function lower() {
echo $1 | tr '[:upper:]' '[:lower:]'
}
##
# Wait for changes to a directory, then do something
#
# @param string $1 The directory to monitor
#
# @return string
##
function monitor_directory() {
MONITOR_DIR="$1"
# Exit when told to
trap 'kill -HUP 0' EXIT
if [ -z $( which inotifywait ) ]; then
echo "inotifywait not installed, exiting"
exit 1
fi
inotifywait -r -e modify,attrib,close_write,move,create,delete --format '%T %:e %f' --timefmt '%c' $MONITOR_DIR
}
##
# Print a message and exit on a non-zero exit code
#
# @param string $1 The exit code
# @param string $2 The error message. Optional.
##
function error() {
# Was there an error?
if [ $1 = 0 ]; then
return
fi
echoc "danger" "$2, exiting..."
exit 1;
}
/usr/bin/do --the --thing=yes
error $? "Error executing do"
############################
#### Print debug info
############################
DEBUG=0
function debug() {
if [[ $DEBUG ]]; then
echoc "info" ">>> $*"
fi
}
# For any debug message
debug "Trying to find config file"
############################
#### Print usage info
############################
cat << EOF
Usage: `basename $0` <command> <arguments>
VERSION: 1.0
Available Commands
install - Install package
uninstall - Uninstall package
update - Update package
list - List packages
EOF
############################
#### Set default values
############################
URL=${URL:-http://localhost:8080}
############################
#### Get a random number
############################
echo $RANDOM
############################
#### Is a program installed?
############################
if [ -z $( which foo ) ]; then
echo "'foo' is not installed!"
fi
##
# Dump a database from the selected server
# ** Note: this script does not lock tables, so is safe to use on production
#
# @param string $1 The database host name
# @param string $2 The database name
##
MYSQL_ROOT_USER=root
MYSQL_ROOT_PASSWORD=foo
function mysql_dump_database() {
if [ -z "$1" ]; then
log "Please specify a mysql server to dump from"
exit 1;
fi
if [ -z "$2" ]; then
log "Please specify a database name to dump"
exit 1;
fi
HOST_NAME=$1
DATABASE_NAME=$2
SQL_FILE=`mktemp -d`/$DATABASE_NAME.$HOST_NAME.sql
echoc "warning" "Dumping data from $HOST_NAME.$DATABASE_NAME to $SQL_FILE"
mysqldump --compress --opt --add-drop-database --skip-lock-tables --single-transaction -u$MYSQL_ROOT_USER -p$MYSQL_ROOT_PASSWORD -h $MYSQL_HOST $DATABASE_NAME > $MYSQL_DUMP_FILENAME
}
##
# Import a database to the local machine
#
# @param string $1 The database name
# @param string $2 The path to the dump file
##
MYSQL_ROOT_USER=root
MYSQL_ROOT_PASSWORD=foo
function mysql_import_database() {
if [ -z "$1" ]; then
log "Please specify a mysql server to import to"
exit 1;
fi
if [ -z "$2" ]; then
log "Please specify a database name to import to"
exit 1;
fi
if [ -z "$3" ]; then
log "Please specify a database dump file to import from"
exit 1;
fi
if [ ! -e "$3" ]; then
log "Database dump file does not exist at: $3"
exit 1;
fi
HOST_NAME=$1
DATABASE_NAME=$2
SQL_FILENAME=$3
echoc "warning" "Dropping $HOST_NAME.$DATABASE_NAME database"
    mysql -u$MYSQL_ROOT_USER -p$MYSQL_ROOT_PASSWORD -h$HOST_NAME << EOF
        DROP DATABASE IF EXISTS $DATABASE_NAME;
        CREATE DATABASE $DATABASE_NAME;
EOF
# Import the database
echoc "warning" "Importing the $HOST_NAME database into $HOST_NAME"
cat "$SQL_FILENAME" | mysql -u$MYSQL_ROOT_USER -p$MYSQL_ROOT_PASSWORD $DATABASE_NAME -h$HOST_NAME
}
##
# Install a node package manager (npm) package
#
# @param string $1 The package to install
##
function npm_install {
if [ -z $( which npm ) ]; then
echoc "info" "Installing NPM"
sudo apt-get -y -qq install npm
fi
if [ ! -e /usr/local/lib/node_modules/$1 ]; then
sudo npm install $1 --global
else
echoc "info" "$1 already installed, skipping"
fi
}
##
# Install a python egg
#
# @param string $1 The egg
##
function python_egg_install {
if [ -z $( which pip ) ]; then
echoc "info" "Installing Python PIP"
sudo apt-get -y -qq install python-setuptools python-pip
fi
IS_EGG_INSTALLED=`pip freeze 2>&1 | grep $1 | wc -l`
if [ "$IS_EGG_INSTALLED" = "0" ]; then
sudo easy_install $1
else
echoc "info" "$1 already installed, skipping"
fi
}
##
# Install a ruby gem
#
# @param string $1 The gem
##
function ruby_gem_install {
if [ -z `which gem` ]; then
echoc "info" "Installing rubygems"
sudo apt-get -y -qq rubygems
fi
IS_GEM_INSTALLED=`gem list -i $1`
if [ "$IS_GEM_INSTALLED" = "false" ]; then
sudo gem install $1
else
echoc "info" "$1 already installed, skipping"
fi
}
############################
#### Iterate over all files in a directory
############################
MY_FILES=`find /path/to/my/files -type f`
for FILE in $MY_FILES; do
echo $FILE
done
############################
#### Replace a single line in a file
############################
MY_CONFIG_FILE=/path/to/my.config
cat $MY_CONFIG_FILE | sed -e "s/^FOO=bar.*$/FOO=buzz/" | sudo tee $MY_CONFIG_FILE
############################
#### Setup git globals
############################
function setup_git_globals() {
git config --global color.branch auto
git config --global color.diff auto
git config --global color.interactive auto
git config --global color.status auto
git config --global color.ui auto
git config --global advice.statusHints false
git config --global branch.autosetupmerge true
}
############################
#### Append to a file owned by root as a non-privileged user
############################
sudo tee -a /etc/hosts << EOF
127.0.0.1 foo.example.com
127.0.0.1 bar.example.com
EOF
############################
#### Create a file owned by root as a non-privileged user
############################
sudo tee /root/foo.txt << EOF
foo
bar
baz
EOF
############################
#### Filter out lines using awk positional filters
############################
awk '$9 ~ /2[0-9][0-9]/ {print $7}' file.txt
############################
#### Crontab docblock
############################
#.-------------------- min (0 - 59)
#| .------------------ hour (0 - 23)
#| | .---------------- day of month (1 - 31)
#| | | .-------------- month (1 - 12)
#| | | | .------------ day of week (0 - 6) (0 to 6 are Sunday to Saturday, or use names; 7 is Sunday, the same as 0)
#| | | | | .---------- user to execute as
#| | | | | | .- command to execute
#* * * * * * -
############################
#### SSL Tools
############################
# Get the SSL Certificate info
export DOMAIN_NAME=example.com
echo | openssl s_client -showcerts -servername $DOMAIN_NAME -connect $DOMAIN_NAME:443 2>/dev/null | openssl x509 -inform pem -noout -text
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment