WordPress Bash Scripts

Published: 22, Jan 2016
DevelopmentLinuxPHPWordPress

I’ve been doing a lot of bash scripting with WordPress, especially with WP CLI. Here are some snippets I found useful.

All the scripts assume a standard wp-config.php file with the database variables set.

Getting the Database table prefix

If you need to make any SQL queries using WP CLI, you will need the database prefix for table names

cat wp-config.php | grep "\$table_prefix" | cut -d \' -f 2

Getting WP Config Database user and password

If you’ve just downloaded an install of WordPress, these will give you the details to retrieve the database

WPDBNAME=`cat wp-config.php | grep DB_NAME | cut -d \' -f 4`
WPDBUSER=`cat wp-config.php | grep DB_USER | cut -d \' -f 4`
WPDBPASS=`cat wp-config.php | grep DB_PASSWORD | cut -d \' -f 4`

Setting WP Config database user and password

If you download a copy of an install, you may have to modify the DB details, this will do that automatically

sed -i "/DB_HOST/s/'[^']*'/'localhost'/2" wp-config.php
sed -i "/DB_NAME/s/'[^']*'/'databasename'/2" wp-config.php
sed -i "/DB_USER/s/'[^']*'/'user'/2" wp-config.php
sed -i "/DB_PASSWORD/s/'[^']*'/'password'/2" wp-config.php

Adding SUNRISE to  wp-config.php

Modifying wp-config.php to add new items isn’t as simple as appending to the end.

sed -i "/define('BLOG_ID_CURRENT_SITE', 1);/ a\
DEFINE( 'SUNRISE', true );\
" wp-config.php

Getting a list of active plugins and looping over them

Here I export the active plugin list as a CSV with a single column and ignore the name entry, letting me iterate through active plugins

active=$(wp plugin list --status=active --format=csv --fields=name)

for plugin in $active; do
	(
		if [ ! $plugin = 'name' ]; then
			echo $plugin
		fi
	)
done

List all blogs via WP CLI

Listing and processing all blogs and sites on a multisite network isn’t as trivial as it’s made out to be, here is how you get the site id, URL, and blog id individually

blogs=$(wp site list --fields="site_id,blog_id,url" --format="csv")
for entry in $blogs
do
    site_id=$(echo $entry |cut -d ',' -f1 )
    blog_id=$(echo $entry |cut -d ',' -f2 )
    blog_url=$(echo $entry |cut -d ',' -f3 )
    echo "$blog_id: $blog_url in $site_id"
done

Installing Domain mapping via WP CLI

Simply installing and activating domain mapping isn’t enough, you need to move sunrise.php and setup the necessary DEFINE in wp-config.php

wp plugin install wordpress-mu-domain-mapping
cp wp-content/plugins/wordpress-mu-domain-mapping/sunrise.php wp-content/sunrise.php
sed -i "/define('BLOG_ID_CURRENT_SITE', 1);/ a\
DEFINE( 'SUNRISE', true );\
" wp-config.php
wp plugin activate wordpress-mu-domain-mapping

Getting the domain name of a WP site via WP CLI

If I’m in an install and want a clean URL such as tomjn.com without the trailing slash and protocol identifier, I would do this:

siteurl=$(wp option get siteurl)
url=$(echo $siteurl | awk -F/ '{print $3}')
echo $url

Get the blog ID of a blog given a URL

WP CLI can list all sites for you, but sometimes you only have a URL to go by and need to find its blog ID

dbprefix=$(cat wp-config.php | grep "\$table_prefix" | cut -d \' -f 2)
query1=$(wp db query "SELECT blog_id FROM ${dbprefix}blogs b WHERE b.domain LIKE \"%${fromdomain}%\" LIMIT 1")
blog_id=$(echo $query1 |cut -d ' ' -f2)
echo $blog_id

Setting Up Domain Mapping via WP CLI

A manual SQL query is needed for this, followed by the setting of some options.

NOTE: Domain mapping only generates the table when you visit the domain mapping admin page, so if you setup a site and run the query it will fail if nobody has logged into the site and visited the network admin panel.

fromdomain='...'
todomain='...'

dbprefix=$(cat wp-config.php | grep "\$table_prefix" | cut -d \' -f 2)
query1=$(wp db query "SELECT blog_id FROM ${dbprefix}blogs b WHERE b.domain LIKE \"%${fromdomain}%\" LIMIT 1")
blog_id=$(echo $query1 |cut -d ' ' -f2)
echo $blog_id
wp db query "INSERT INTO ${dbprefix}domain_mapping ( blog_id, domain, active ) VALUES ( $blog_id, \"${todomain}\", 1 )"

wp option update home "http://${todomain}" --url="${todomain}"
wp option update siteurl "http://${todomain}" --url="${todomain}"