Created
December 23, 2013 07:40
-
-
Save ryansechrest/8093056 to your computer and use it in GitHub Desktop.
Bash script to synchronize website directory and database between server and localhost or server and server.
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
#!/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 |
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
#!/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