Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Bash script to synchronize website directory and database between server and localhost or server and server.
#!/bin/bash
# Created on 10/8/13 by Ryan Sechrest
# site (localhost edition)
# Program to mirror a directory and database of a website between two servers.
### Program meta data
# Program name
NAME='site'
# Program version
VERSION='1.0.0'
# Today's date
DATE=$(date +'%x %r %Z')
# Program header title
TITLE="Site v$VERSION on $HOSTNAME"
# Program header information
STATUS="$DATE by $USER"
# Program usage help
USAGE="Usage: $NAME [sync|update] [sitename]"
### Production database server
# Hostname or IP address
MYSQL_PRD_HOSTNAME='hostname'
# Username
MYSQL_PRD_USERNAME='username'
### Localhost database server
# Username
MYSQL_LOCAL_USERNAME='hostname'
# Password
MYSQL_LOCAL_PASSWORD='username'
### Production web server
# Hostname or IP address
SSH_PRD_HOSTNAME='hostname'
# Username
SSH_PRD_USERNAME='username'
### Local server paths
# Absolute path to local sites directory
# Ex: /Users/$USER/Sites
LOCAL_SITES_PATH="/Users/$USER/Sites"
# Absolute path to production sites directory
# Ex: /var/www/domains
PRD_SITES_PATH='/var/www/domains'
# Absolute path to local temporary sites directory
# Ex: /Volumes/Shared
TEMP_SITES_PATH='/Volumes/Shared'
### Executable shortcuts
# Path to various executables
# Ex: /Applications/MAMP/Library/bin
BIN_PATH='/Applications/MAMP/Library/bin'
# Path to 'mysql' executable
# Ex: $BIN_PATH/mysql
MYSQL="$BIN_PATH/mysql"
# Path to 'mysqldump' executable
# Ex: $BIN_PATH/mysqldump
MYSQLDUMP="$BIN_PATH/mysqldump"
### Save program arguments
arg1=$1
arg2=$2
### Display functions
# Display divider
function display_divider {
echo '------------------------------------------------------------'
}
# Display new line
function display_newline {
echo
}
# Display output start
function display_output_start {
echo '> Starting...'
}
# Display output end
function display_output_end {
echo '> Done.'
}
# Display program header
function display_header {
display_newline
display_divider
echo " $TITLE"
echo " $STATUS"
echo " $ $NAME $arg1 $arg2"
display_divider
display_newline
}
# Display usage help
function display_usage {
echo $USAGE
display_newline
}
### MySQL functions
# Update imported database to match local environment
# $1 mysql hostname
# $2 mysql username
# $3 mysql password
# $4 mydql database
# $5 domain name
function wp_mu_db_update {
user=$1
pass=$2
db=$3
query="$MYSQL --user=$user --password=$pass $db -e"
echo "> Setting 'domain' field in 'wp_blogs' table to 'localhost'..."
$query "UPDATE wp_blogs SET domain = 'localhost' WHERE blog_id = 1 AND site_id = 1";
echo "> Setting 'site_url' field in 'wp_options' table to 'http://localhost/wordpress'..."
$query "UPDATE wp_options SET option_value = 'http://localhost/wordpress' WHERE option_name = 'siteurl'";
echo "> Setting 'home' field in 'wp_options' to 'http://localhost'..."
$query "UPDATE wp_options SET option_value = 'http://localhost/' WHERE option_name = 'home'";
echo "> Setting 'domain' field in 'wp_site' to 'localhost'..."
$query "UPDATE wp_site SET domain = 'localhost' WHERE id = 1";
echo "> Setting 'site_url' field in 'wp_sitemeta' table to 'http://localhost/'..."
$query "UPDATE wp_sitemeta SET meta_value = 'http://localhost/' WHERE meta_key = 'siteurl' AND site_id = 1";
}
### Main Functions
# rsync
# -a, --archive archive mode; same as -rlptgoD
# -r, --recursive recurse into directories
# -l, --links copy symlinks as symlinks
# -p, --perms preserve permissions
# -t, --times preserve times
# -g, --group preserve group
# -o, --owner preserve owner (super-user only)
# -D same as --devices --specials
# --devices preserve device files (super-user only)
# --specials preserve special files
# -v, --verbose increase verbosity
# --exclude=PATTERN exclude files matching PATTERN
# --delete delete files that don’t exist on sender
# --delete-excluded also delete excluded files on receiver
# Copy files from production web server to temporary directory
# $1 path to files on production server
# $2 path to files on local server
# $3 rsync exclude option(s)
function download_files {
src=$1
dst=$2
ex=$3
if [ ! -d "$dst" ]; then
echo "> Creating temporary directory..."
echo " $dst"
mkdir -p "$dst"
fi
if [ -d "$dst" ]; then
echo "> Synchronizing production files with temporary directory..."
echo " Source : $src"
echo " Destination : $dst"
rsync --archive --verbose $ex --delete --delete-excluded "$src" "$dst"
else
echo "> Temporary directory does not exist"
echo " $dst"
fi
}
# Export database from production database server to temporary directory
# $1 database hostname
# $2 database username
# $3 database name
# $4 path to save mysql export
# $5 mysqldump ignore-table option(s)
function export_database {
host=$1
user=$2
db=$3
dst=$4
ignore=$5
if [ ! -d "$dst" ]; then
echo "> Creating temporary directory..."
echo " $dst"
mkdir -p "$dst"
fi
if [ -d "$dst" ]; then
echo "> Exporting production database to temporary directory..."
echo " Database : $db"
echo " Destination : $dst"
echo " Filename : $db.sql"
$MYSQLDUMP --verbose --host=$host --user=$user --password $db $ignore > "$dst/$db.sql"
else
echo "> Temporary directory does not exist"
echo " $dst"
fi
}
# Copy files from temporary directory to local site
# $1 path to temporary files on local server
# $2 path to real files on local server
function upload_files {
src=$1
dst=$2
if [[ (-d "$src") && (-d "$dst") ]]; then
echo "> Synchronizing temporary files with local site directory..."
echo " Source : $src"
echo " Destination : $dst"
rsync --archive --delete --delete-excluded "$src" "$dst"
else
echo "> Temporary or local site directory does not exist"
echo " Source : $src"
echo " Destination : $dst"
fi
}
# Import production database from temporary directory to local database
# $1 database hostname
# $2 database username
# $3 database password
# $4 database name
# $5 path to mysql export
function import_database {
user=$1
pass=$2
db=$3
src=$4
if [ -f "$src/$db.sql" ]; then
echo "> Importing temporary database export into local database..."
echo " Filename : $db.sql"
echo " Source : $src"
echo " Database : $db"
$MYSQL --user=$user --password=$pass $db < "$src/$db.sql"
else
echo "> Temporary database export does not exist"
echo " Filename : $db.sql"
echo " Source : $src"
fi
}
### Run Functions
# Run sync component
function run_sync {
case $arg2 in
sitename)
display_output_start
copy_from="$SSH_PRD_USERNAME@$SSH_PRD_HOSTNAME:$PRD_SITES_PATH/domain.com/www/htdocs/wp-content/uploads/"
copy_to="$TEMP_SITES_PATH/$arg2/uploads/"
exclude='--exclude=temp --exclude=wpcf7_uploads'
download_files "$copy_from" "$copy_to" "$exclude"
display_newline
mysql_hostname=$MYSQL_PRD_HOSTNAME
mysql_username=$MYSQL_PRD_USERNAME
mysql_database='domain_com'
export_to="$TEMP_SITES_PATH/$arg2"
ignore="--ignore-table=$mysql_database.wp_w3tc_cdn_queue"
export_database $mysql_hostname $mysql_username $mysql_database "$export_to" "$ignore"
display_output_end
;;
*)
display_usage
;;
esac
}
# Run update component
function run_update {
case $arg2 in
sitename)
display_output_start
copy_from="$TEMP_SITES_PATH/$arg2/uploads/"
copy_to="$LOCAL_SITES_PATH/domain.com/www/htdocs/wp-content/uploads/"
upload_files "$copy_from" "$copy_to"
mysql_username=$MYSQL_LOCAL_USERNAME
mysql_password=$MYSQL_LOCAL_PASSWORD
mysql_database='domain_com'
import_from="$TEMP_SITES_PATH/$arg2"
import_database $mysql_username $mysql_password $mysql_database "$import_from"
wp_mu_db_update $mysql_username $mysql_password $mysql_database
display_output_end
;;
*)
display_usage
;;
esac
}
# Run main component
function run {
case $arg1 in
sync)
run_sync
display_newline
;;
update)
run_update
display_newline
;;
*)
display_usage
;;
esac
}
### Run Program
display_header
run
exit 0
#!/bin/bash
# Created on 10/2/13 by Ryan Sechrest
# site (server edition)
# Program to mirror a directory and database of a website between two servers.
### Program meta data
# Program name
NAME='site'
# Program version
VERSION='1.0.0'
# Today's date
DATE=$(date +'%x %r %Z')
# Program header title
TITLE="Site v$VERSION on $HOSTNAME"
# Program header information
STATUS="$DATE by $USER"
# Program usage help
USAGE="Usage: $NAME [sync|update] [sitename]"
### Server environment
ENV=''
case $HOSTNAME in
DEV01.DOMAIN.COM)
ENV='DEV'
;;
STG01.DOMAIN.COM)
ENV='STG'
;;
esac
### Production database server
# Hostname or IP address
MYSQL_PRD_HOSTNAME='hostname'
# Username
MYSQL_PRD_USERNAME='username'
### Production web server
# Hostname or IP address
SSH_PRD_HOSTNAME='hostname'
# Username
SSH_PRD_USERNAME='username'
### Local server paths
# Absolute path to local sites directory
# Ex: /var/www/domains
LOCAL_SITES_PATH='/var/www/domains'
# Absolute path to production sites directory
# Ex: /var/www/domains
PRD_SITES_PATH='/var/www/domains'
# Absolute path to local temporary sites directory
# Ex: /opt/sites
TEMP_SITES_PATH='/opt/sites'
### Save program arguments
arg1=$1
arg2=$2
### Display functions
# Display divider
function display_divider {
echo '------------------------------------------------------------'
}
# Display new line
function display_newline {
echo
}
# Display output start
function display_output_start {
echo '> Starting...'
}
# Display output end
function display_output_end {
echo '> Done.'
}
# Display program header
function display_header {
display_newline
display_divider
echo " $TITLE"
echo " $STATUS"
echo " $ $NAME $arg1 $arg2"
display_divider
display_newline
}
# Display usage help
function display_usage {
echo $USAGE
display_newline
}
### MySQL functions
# Update imported database to match local environment
# $1 mysql hostname
# $2 mysql username
# $3 mysql password
# $4 mydql database
# $5 domain name
function wp_mu_db_update {
host=$1
user=$2
pass=$3
db=$4
domain=$5
query="mysql --host=$host --user=$user --password=$pass $db -e"
echo "> Setting 'domain' field in 'wp_blogs' table to '$domain'..."
$query "UPDATE wp_blogs SET domain = '$domain' WHERE blog_id = 1 AND site_id = 1";
echo "> Setting 'site_url' field in 'wp_options' table to 'http://$domain/wordpress'..."
$query "UPDATE wp_options SET option_value = 'http://$domain/wordpress' WHERE option_name = 'siteurl'";
echo "> Setting 'home' field in 'wp_options' to 'http://$domain'..."
$query "UPDATE wp_options SET option_value = 'http://$domain/' WHERE option_name = 'home'";
echo "> Setting 'domain' field in 'wp_site' to '$domain'..."
$query "UPDATE wp_site SET domain = '$domain' WHERE id = 1";
echo "> Setting 'site_url' field in 'wp_sitemeta' table to 'http://$domain/'..."
$query "UPDATE wp_sitemeta SET meta_value = 'http://$domain/' WHERE meta_key = 'siteurl' AND site_id = 1";
}
### Main functions
# rsync
# -a, --archive archive mode; same as -rlptgoD
# -r, --recursive recurse into directories
# -l, --links copy symlinks as symlinks
# -p, --perms preserve permissions
# -t, --times preserve times
# -g, --group preserve group
# -o, --owner preserve owner (super-user only)
# -D same as --devices --specials
# --devices preserve device files (super-user only)
# --specials preserve special files
# -v, --verbose increase verbosity
# --exclude=PATTERN exclude files matching PATTERN
# --delete delete files that don’t exist on sender
# --delete-excluded also delete excluded files on receiver
# Copy files from production web server to temporary directory
# $1 path to files on production server
# $2 path to files on local server
# $3 rsync exclude option(s)
function download_files {
src=$1
dst=$2
ex=$3
if [ ! -d "$dst" ]; then
echo "> Creating temporary directory..."
echo " $dst"
mkdir -p "$dst"
fi
if [ -d "$dst" ]; then
echo "> Synchronizing production files with temporary directory..."
echo " Source : $src"
echo " Destination : $dst"
rsync --archive --verbose $ex --delete --delete-excluded "$src" "$dst"
else
echo "> Temporary directory does not exist"
echo " $dst"
fi
}
# Export database from production database server to temporary directory
# $1 database hostname
# $2 database username
# $3 database name
# $4 path to save mysql export
# $5 mysqldump ignore-table option(s)
function export_database {
host=$1
user=$2
db=$3
dst=$4
ignore=$5
if [ ! -d "$dst" ]; then
echo "> Creating temporary directory..."
echo " $dst"
mkdir -p "$dst"
fi
if [ -d "$dst" ]; then
echo "> Exporting production database to temporary directory..."
echo " Database : $db"
echo " Destination : $dst"
echo " Filename : $db.sql"
mysqldump --verbose --host=$host --user=$user --password $db $ignore > "$dst/$db.sql"
else
echo "> Temporary directory does not exist"
echo " $dst"
fi
}
# Copy files from temporary directory to local site
# $1 path to temporary files on local server
# $2 path to real files on local server
function upload_files {
src=$1
dst=$2
if [[ (-d "$src") && (-d "$dst") ]]; then
echo "> Synchronizing temporary files with local site directory..."
echo " Source : $src"
echo " Destination : $dst"
rsync --archive --delete --delete-excluded "$src" "$dst"
else
echo "> Temporary or local site directory does not exist"
echo " Source : $src"
echo " Destination : $dst"
fi
}
# Import production database from temporary directory to local database
# $1 database hostname
# $2 database username
# $3 database password
# $4 database name
# $5 path to mysql export
function import_database {
host=$1
user=$2
pass=$3
db=$4
src=$5
if [ -f "$src/$db.sql" ]; then
echo "> Importing temporary database export into local database..."
echo " Filename : $db.sql"
echo " Source : $src"
echo " Database : $db"
mysql --host=$host --user=$user --password=$pass $db < "$src/$db.sql"
else
echo "> Temporary database export does not exist"
echo " Filename : $db.sql"
echo " Source : $src"
fi
}
### Run functions
# Run sync component
function run_sync {
case $arg2 in
sitename)
display_output_start
copy_from="$SSH_PRD_USERNAME@$SSH_PRD_HOSTNAME:$PRD_SITES_PATH/domain.com/www/htdocs/wp-content/uploads/"
copy_to="$TEMP_SITES_PATH/$arg2/uploads/"
exclude='--exclude=temp --exclude=wpcf7_uploads'
download_files "$copy_from" "$copy_to" "$exclude"
display_newline
mysql_hostname=$MYSQL_PRD_HOSTNAME
mysql_username=$MYSQL_PRD_USERNAME
mysql_database='domain_com'
export_to="$TEMP_SITES_PATH/$arg2"
ignore="--ignore-table=$mysql_database.wp_w3tc_cdn_queue"
export_database $mysql_hostname $mysql_username $mysql_database "$export_to" "$ignore"
display_output_end
;;
*)
display_usage
;;
esac
}
# Run update component
function run_update {
case $arg2 in
sitename)
display_output_start
copy_from="$TEMP_SITES_PATH/$arg2/uploads/"
copy_to="$LOCAL_SITES_PATH/domain.com/www/htdocs/wp-content/uploads/"
upload_files "$copy_from" "$copy_to"
mysql_username=''
mysql_password=''
domain_name=''
case $ENV in
DEV)
mysql_username='username'
mysql_password='password'
domain_name='dev01.domain.com'
;;
STG)
mysql_username='username'
mysql_password='password'
domain_name='stg01.domain.com'
;;
esac
if [[ (-n $mysql_username) && (-n $mysql_password) && (-n $domain_name) ]]; then
mysql_hostname='localhost'
mysql_database='domain_com'
import_from="$TEMP_SITES_PATH/$arg2"
import_database $mysql_hostname $mysql_username $mysql_password $mysql_database "$import_from"
wp_mu_db_update $mysql_hostname $mysql_username $mysql_password $mysql_database $domain_name
else
echo "> Unable to obtain MySQL credentials for $ENV server"
fi
display_output_end
;;
*)
display_usage
;;
esac
}
# Run main component
function run {
case $arg1 in
sync)
run_sync
display_newline
;;
update)
run_update
display_newline
;;
*)
display_usage
;;
esac
}
### Run Program
display_header
run
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment