Last active
June 3, 2019 17:20
-
-
Save taeram/6231524 to your computer and use it in GitHub Desktop.
Handy Bash Code Snippets and functions
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
############################ | |
#### 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