<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>bash functions Archives - WP-CLI Mastery</title>
	<atom:link href="https://wpclimastery.com/blog/tag/bash-functions/feed/" rel="self" type="application/rss+xml" />
	<link>https://wpclimastery.com/blog/tag/bash-functions/</link>
	<description>Automate WordPress Like a DevOps Pro.</description>
	<lastBuildDate>Wed, 12 Nov 2025 19:57:32 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://wpclimastery.com/wp-content/uploads/2025/11/cropped-favicon-32x32.webp</url>
	<title>bash functions Archives - WP-CLI Mastery</title>
	<link>https://wpclimastery.com/blog/tag/bash-functions/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Writing Reusable Bash Functions for WordPress Automation</title>
		<link>https://wpclimastery.com/blog/writing-reusable-bash-functions-for-wordpress-automation/</link>
					<comments>https://wpclimastery.com/blog/writing-reusable-bash-functions-for-wordpress-automation/#respond</comments>
		
		<dc:creator><![CDATA[Krasen]]></dc:creator>
		<pubDate>Mon, 10 Nov 2025 09:00:00 +0000</pubDate>
				<category><![CDATA[Bash Scripting for WordPress]]></category>
		<category><![CDATA[bash functions]]></category>
		<category><![CDATA[bash wordpress automation]]></category>
		<category><![CDATA[reusable bash code]]></category>
		<category><![CDATA[shell functions wordpress]]></category>
		<category><![CDATA[wordpress bash]]></category>
		<guid isPermaLink="false">https://wpclimastery.com/writing-reusable-bash-functions-for-wordpress-automation/</guid>

					<description><![CDATA[<p>If you&#8217;re writing WordPress automation scripts with WP-CLI, you&#8217;ve probably found yourself copy-pasting the same code blocks over and over. Database exports, plugin updates, backup routines—the same patterns repeat across...</p>
<p>The post <a href="https://wpclimastery.com/blog/writing-reusable-bash-functions-for-wordpress-automation/">Writing Reusable Bash Functions for WordPress Automation</a> appeared first on <a href="https://wpclimastery.com">WP-CLI Mastery</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>If you&#8217;re writing WordPress automation scripts with WP-CLI, you&#8217;ve probably found yourself copy-pasting the same code blocks over and over. Database exports, plugin updates, backup routines—the same patterns repeat across different scripts.</p>



<p>This is where Bash functions become your secret weapon.</p>



<p>In this guide, you&#8217;ll learn how to write reusable, production-ready Bash functions for WordPress automation. We&#8217;ll cover parameter validation, error handling, logging, and real-world examples you can use immediately in your WP-CLI scripts.</p>



<h3 class="wp-block-heading" id="why-use-functions-in-bash-scripts-why-functions">Why Use Functions in Bash Scripts?</h3>



<p>Functions are reusable blocks of code that make your scripts:</p>



<p><strong>More Maintainable</strong>: Fix a bug once in the function, not in 10 different scripts.</p>



<p><strong>Easier to Read</strong>:&nbsp;<code>backup_wordpress_database</code>&nbsp;is clearer than 20 lines of inline code.</p>



<p><strong>More Testable</strong>: Test individual functions independently.</p>



<p><strong>DRY (Don&#8217;t Repeat Yourself)</strong>: Write once, use everywhere.</p>



<p><strong>Professional</strong>: Production-ready scripts use functions extensively.</p>



<h4 class="wp-block-heading" id="before-functions-repetitive-code">Before Functions: Repetitive Code</h4>



<p>Here&#8217;s what many WordPress automation scripts look like without functions:</p>



<pre class="wp-block-code"><code>#!/bin/bash
<em># Script 1: Backup site A</em>
cd /var/www/siteA
wp db export /backups/siteA-$(date +%Y%m%d).sql
tar -czf /backups/siteA-files-$(date +%Y%m%d).tar.gz .
echo "Backup completed for Site A"

<em># Script 2: Backup site B (almost identical!)</em>
cd /var/www/siteB
wp db export /backups/siteB-$(date +%Y%m%d).sql
tar -czf /backups/siteB-files-$(date +%Y%m%d).tar.gz .
echo "Backup completed for Site B"
</code></pre>



<p>This violates DRY principles and becomes a maintenance nightmare.</p>



<h4 class="wp-block-heading" id="after-functions-clean-and-reusable">After Functions: Clean and Reusable</h4>



<p>With functions, the same logic becomes:</p>



<pre class="wp-block-code"><code>#!/bin/bash

<em># Reusable function</em>
backup_wordpress() {
    local wp_path=$1
    local backup_dir=$2
    local site_name=$(basename "$wp_path")
    local timestamp=$(date +%Y%m%d)

    cd "$wp_path" || return 1
    wp db export "${backup_dir}/${site_name}-${timestamp}.sql" || return 1
    tar -czf "${backup_dir}/${site_name}-files-${timestamp}.tar.gz" . || return 1
    echo "Backup completed for ${site_name}"
}

<em># Use the function</em>
backup_wordpress /var/www/siteA /backups
backup_wordpress /var/www/siteB /backups
backup_wordpress /var/www/siteC /backups
</code></pre>



<p>One function, multiple uses. Change the backup logic once, and all three sites benefit.</p>



<h3 class="wp-block-heading" id="basic-function-syntax-basic-syntax">Basic Function Syntax {#basic-syntax}</h3>



<p>Bash functions can be defined in two ways:</p>



<h4 class="wp-block-heading" id="method-1-using-the-function-keyword">Method 1: Using the&nbsp;<code>function</code>&nbsp;Keyword</h4>



<pre class="wp-block-code"><code>function my_function() {
    echo "Hello from my function"
}
</code></pre>



<h4 class="wp-block-heading" id="method-2-without-the-function-keyword-posix-compliant">Method 2: Without the&nbsp;<code>function</code>&nbsp;Keyword (POSIX-compliant)</h4>



<pre class="wp-block-code"><code>my_function() {
    echo "Hello from my function"
}
</code></pre>



<p>Both work identically. Method 2 is more portable and preferred for production scripts.</p>



<h4 class="wp-block-heading" id="calling-functions">Calling Functions</h4>



<p>Simply use the function name:</p>



<pre class="wp-block-code"><code>my_function  <em># Calls the function</em>
</code></pre>



<h4 class="wp-block-heading" id="example-simple-wordpress-function">Example: Simple WordPress Function</h4>



<pre class="wp-block-code"><code>#!/bin/bash

<em># Function to check WordPress version</em>
check_wp_version() {
    wp core version
}

<em># Call it</em>
check_wp_version
</code></pre>



<p><strong>Output:</strong></p>



<pre class="wp-block-code"><code>6.4.2
</code></pre>



<h3 class="wp-block-heading" id="parameter-handling-in-functions-parameters">Parameter Handling in Functions</h3>



<p>Functions accept parameters just like scripts. Parameters are accessed using&nbsp;<code>$1</code>,&nbsp;<code>$2</code>,&nbsp;<code>$3</code>, etc.</p>



<h4 class="wp-block-heading" id="basic-parameters">Basic Parameters</h4>



<pre class="wp-block-code"><code>greet_user() {
    local name=$1
    echo "Hello, ${name}!"
}

greet_user "John"  <em># Output: Hello, John!</em>
</code></pre>



<h4 class="wp-block-heading" id="multiple-parameters">Multiple Parameters</h4>



<pre class="wp-block-code"><code>update_wordpress() {
    local wp_path=$1
    local backup=$2

    cd "$wp_path" || return 1

    if &#91; "$backup" = "yes" ]; then
        wp db export backup.sql
    fi

    wp core update
}

<em># Usage</em>
update_wordpress /var/www/html yes
</code></pre>



<h4 class="wp-block-heading" id="parameter-variables">Parameter Variables</h4>



<p>Bash provides special variables for working with parameters:</p>



<ul class="wp-block-list">
<li><code>$#</code>&nbsp;&#8211; Number of parameters</li>



<li><code>$@</code>&nbsp;&#8211; All parameters as separate strings</li>



<li><code>$*</code>&nbsp;&#8211; All parameters as single string</li>



<li><code>$1, $2, ...</code>&nbsp;&#8211; Individual parameters</li>
</ul>



<h4 class="wp-block-heading" id="wordpress-example-plugin-update-function">WordPress Example: Plugin Update Function</h4>



<pre class="wp-block-code"><code>update_plugin() {
    local wp_path=$1
    local plugin_name=$2

    echo "Updating plugin: ${plugin_name} at ${wp_path}"
    wp plugin update "$plugin_name" --path="$wp_path"
}

<em># Usage</em>
update_plugin /var/www/html woocommerce
update_plugin /var/www/html yoast-seo
</code></pre>



<h3 class="wp-block-heading" id="return-values-and-exit-codes-return-values">Return Values and Exit Codes</h3>



<p>Bash functions don&#8217;t return values like other programming languages. Instead, they use:</p>



<ol class="wp-block-list">
<li><strong>Exit codes</strong>&nbsp;(0 for success, non-zero for failure)</li>



<li><strong>Echo statements</strong>&nbsp;(output that can be captured)</li>
</ol>



<h4 class="wp-block-heading" id="exit-codes-with-return">Exit Codes with&nbsp;<code>return</code></h4>



<pre class="wp-block-code"><code>check_wordpress_exists() {
    local wp_path=$1

    if &#91; -f "${wp_path}/wp-config.php" ]; then
        return 0  <em># Success</em>
    else
        return 1  <em># Failure</em>
    fi
}

<em># Usage</em>
if check_wordpress_exists /var/www/html; then
    echo "WordPress found!"
else
    echo "WordPress not found"
fi
</code></pre>



<p><strong>Best Practice</strong>: Always return 0 for success, 1+ for errors. This follows Unix conventions and works with&nbsp;<code>if</code>&nbsp;statements.</p>



<h4 class="wp-block-heading" id="returning-values-via-echo">Returning Values via Echo</h4>



<pre class="wp-block-code"><code>get_wordpress_version() {
    local wp_path=$1
    wp core version --path="$wp_path"
}

<em># Capture output</em>
version=$(get_wordpress_version /var/www/html)
echo "WordPress version: ${version}"
</code></pre>



<h4 class="wp-block-heading" id="combining-both-approaches">Combining Both Approaches</h4>



<pre class="wp-block-code"><code>backup_database() {
    local wp_path=$1
    local backup_file=$2

    <em># Perform backup</em>
    if wp db export "$backup_file" --path="$wp_path" 2&gt;/dev/null; then
        echo "$backup_file"  <em># Return filename</em>
        return 0             <em># Success exit code</em>
    else
        echo ""              <em># Return empty string</em>
        return 1             <em># Failure exit code</em>
    fi
}

<em># Usage</em>
if backup_file=$(backup_database /var/www/html "/backups/db.sql"); then
    echo "Backup successful: ${backup_file}"
else
    echo "Backup failed"
fi
</code></pre>



<h3 class="wp-block-heading" id="error-handling-best-practices-error-handling">Error Handling Best Practices</h3>



<p>Production-ready functions need robust error handling. Here&#8217;s how to do it right.</p>



<h4 class="wp-block-heading" id="use-set--e-cautiously">Use&nbsp;<code>set -e</code>&nbsp;Cautiously</h4>



<pre class="wp-block-code"><code>#!/bin/bash
set -e  <em># Exit on any error</em>

<em># This will exit the entire script if wp fails</em>
wp plugin update --all
</code></pre>



<p><strong>Problem</strong>:&nbsp;<code>set -e</code>&nbsp;exits the entire script on first error, which might not be what you want in functions.</p>



<p><strong>Better approach</strong>: Handle errors explicitly in functions.</p>



<h4 class="wp-block-heading" id="check-command-success">Check Command Success</h4>



<pre class="wp-block-code"><code>update_all_plugins() {
    local wp_path=$1

    if ! wp plugin update --all --path="$wp_path"; then
        echo "ERROR: Plugin update failed" &gt;&amp;2
        return 1
    fi

    echo "All plugins updated successfully"
    return 0
}
</code></pre>



<h4 class="wp-block-heading" id="validate-parameters">Validate Parameters</h4>



<pre class="wp-block-code"><code>backup_wordpress() {
    local wp_path=$1
    local backup_dir=$2

    <em># Validate parameters exist</em>
    if &#91; -z "$wp_path" ] || &#91; -z "$backup_dir" ]; then
        echo "ERROR: Missing parameters" &gt;&amp;2
        echo "Usage: backup_wordpress &lt;wp_path&gt; &lt;backup_dir&gt;" &gt;&amp;2
        return 1
    fi

    <em># Validate WordPress directory</em>
    if &#91; ! -f "${wp_path}/wp-config.php" ]; then
        echo "ERROR: Not a WordPress installation: ${wp_path}" &gt;&amp;2
        return 1
    fi

    <em># Validate backup directory</em>
    if &#91; ! -d "$backup_dir" ]; then
        echo "ERROR: Backup directory doesn't exist: ${backup_dir}" &gt;&amp;2
        return 1
    fi

    <em># Perform backup</em>
    <em># ... backup logic here ...</em>
}
</code></pre>



<h4 class="wp-block-heading" id="use-error-messages-to-stderr">Use Error Messages to STDERR</h4>



<p>Send errors to&nbsp;<code>stderr</code>&nbsp;(file descriptor 2) instead of&nbsp;<code>stdout</code>:</p>



<pre class="wp-block-code"><code>log_error() {
    echo "&#91;ERROR] $*" &gt;&amp;2
}

log_info() {
    echo "&#91;INFO] $*"
}

<em># Usage</em>
if ! wp core update; then
    log_error "WordPress core update failed"
    return 1
fi

log_info "WordPress updated successfully"
</code></pre>



<p>This allows users to separate errors from normal output:</p>



<pre class="wp-block-code"><code>./script.sh 2&gt;errors.log  <em># Only errors go to file</em>
./script.sh 2&gt;&amp;1 | grep ERROR  <em># Search errors</em>
</code></pre>



<h3 class="wp-block-heading" id="real-world-wordpress-functions-wordpress-functions">Real-World WordPress Functions {#wordpress-functions}</h3>



<p>Let&#8217;s build production-ready functions you can use immediately.</p>



<h4 class="wp-block-heading" id="function-1-wordpress-site-backup">Function 1: WordPress Site Backup</h4>



<pre class="wp-block-code"><code>#!/bin/bash

backup_wordpress_site() {
    local wp_path=$1
    local backup_dir=$2
    local timestamp=$(date +%Y%m%d_%H%M%S)
    local site_name=$(basename "$wp_path")

    <em># Validate inputs</em>
    if &#91; -z "$wp_path" ] || &#91; -z "$backup_dir" ]; then
        echo "ERROR: Usage: backup_wordpress_site &lt;wp_path&gt; &lt;backup_dir&gt;" &gt;&amp;2
        return 1
    fi

    if &#91; ! -f "${wp_path}/wp-config.php" ]; then
        echo "ERROR: Invalid WordPress path: ${wp_path}" &gt;&amp;2
        return 1
    fi

    <em># Create backup directory if needed</em>
    mkdir -p "$backup_dir"

    <em># Backup database</em>
    local db_file="${backup_dir}/${site_name}_db_${timestamp}.sql"
    echo "Backing up database..."
    if ! wp db export "$db_file" --path="$wp_path" --quiet; then
        echo "ERROR: Database backup failed" &gt;&amp;2
        return 1
    fi

    <em># Compress database</em>
    gzip "$db_file"
    echo "Database backed up: ${db_file}.gz"

    <em># Backup files</em>
    local files_archive="${backup_dir}/${site_name}_files_${timestamp}.tar.gz"
    echo "Backing up files..."
    if ! tar -czf "$files_archive" -C "$(dirname $wp_path)" "$(basename $wp_path)" 2&gt;/dev/null; then
        echo "ERROR: File backup failed" &gt;&amp;2
        return 1
    fi

    echo "Files backed up: ${files_archive}"
    echo "Backup completed successfully"
    return 0
}

<em># Usage</em>
backup_wordpress_site /var/www/html /backups
</code></pre>



<h4 class="wp-block-heading" id="function-2-bulk-plugin-update-with-verification">Function 2: Bulk Plugin Update with Verification</h4>



<pre class="wp-block-code"><code>update_plugins_safe() {
    local wp_path=$1

    <em># Validation</em>
    if &#91; ! -f "${wp_path}/wp-config.php" ]; then
        echo "ERROR: Invalid WordPress path" &gt;&amp;2
        return 1
    fi

    echo "Checking for plugin updates..."
    local updates=$(wp plugin list --update=available --path="$wp_path" --format=count)

    if &#91; "$updates" -eq 0 ]; then
        echo "All plugins are up to date"
        return 0
    fi

    echo "Found ${updates} plugin(s) to update"

    <em># Backup database before updates</em>
    local backup_file="/tmp/pre-update-backup-$(date +%s).sql"
    echo "Creating safety backup..."
    if ! wp db export "$backup_file" --path="$wp_path" --quiet; then
        echo "ERROR: Safety backup failed, aborting" &gt;&amp;2
        return 1
    fi

    echo "Updating plugins..."
    if wp plugin update --all --path="$wp_path"; then
        echo "Plugins updated successfully"
        rm -f "$backup_file"  <em># Clean up backup if successful</em>
        return 0
    else
        echo "ERROR: Plugin update failed" &gt;&amp;2
        echo "Safety backup available at: ${backup_file}"
        return 1
    fi
}

<em># Usage</em>
update_plugins_safe /var/www/html
</code></pre>



<h4 class="wp-block-heading" id="function-3-wordpress-health-check">Function 3: WordPress Health Check</h4>



<pre class="wp-block-code"><code>wordpress_health_check() {
    local wp_path=$1
    local errors=0

    echo "Running WordPress health check for: ${wp_path}"
    echo "=============================================="

    <em># Check 1: WordPress core</em>
    echo -n "WordPress Core: "
    if wp core verify-checksums --path="$wp_path" &amp;&gt;/dev/null; then
        echo "✓ OK"
    else
        echo "✗ FAILED"
        ((errors++))
    fi

    <em># Check 2: Database</em>
    echo -n "Database Connection: "
    if wp db check --path="$wp_path" &amp;&gt;/dev/null; then
        echo "✓ OK"
    else
        echo "✗ FAILED"
        ((errors++))
    fi

    <em># Check 3: Plugin updates</em>
    echo -n "Plugin Updates: "
    local plugin_updates=$(wp plugin list --update=available --path="$wp_path" --format=count)
    if &#91; "$plugin_updates" -eq 0 ]; then
        echo "✓ All up to date"
    else
        echo "⚠ ${plugin_updates} update(s) available"
    fi

    <em># Check 4: Theme updates</em>
    echo -n "Theme Updates: "
    local theme_updates=$(wp theme list --update=available --path="$wp_path" --format=count)
    if &#91; "$theme_updates" -eq 0 ]; then
        echo "✓ All up to date"
    else
        echo "⚠ ${theme_updates} update(s) available"
    fi

    <em># Check 5: Core version</em>
    local wp_version=$(wp core version --path="$wp_path")
    echo "WordPress Version: ${wp_version}"

    echo "=============================================="
    if &#91; $errors -eq 0 ]; then
        echo "Health check passed"
        return 0
    else
        echo "Health check failed with ${errors} error(s)"
        return 1
    fi
}

<em># Usage</em>
wordpress_health_check /var/www/html
</code></pre>



<h3 class="wp-block-heading" id="building-a-function-library-function-library">Building a Function Library {#function-library}</h3>



<p>Create a reusable library that you can source into any WordPress automation script.</p>



<h4 class="wp-block-heading" id="create-the-library-file">Create the Library File</h4>



<pre class="wp-block-code"><code><em># Save as: ~/wp-functions.sh</em>

<em>#!/bin/bash</em>
<em>#</em>
<em># WordPress Automation Function Library</em>
<em># Source this file in your scripts: source ~/wp-functions.sh</em>
<em>#</em>

<em># Color codes for output</em>
RED='\033&#91;0;31m'
GREEN='\033&#91;0;32m'
YELLOW='\033&#91;1;33m'
NC='\033&#91;0m' <em># No Color</em>

<em># Logging functions</em>
log_info() {
    echo -e "${GREEN}&#91;INFO]${NC} $*"
}

log_error() {
    echo -e "${RED}&#91;ERROR]${NC} $*" &gt;&amp;2
}

log_warning() {
    echo -e "${YELLOW}&#91;WARNING]${NC} $*"
}

<em># Check if path is valid WordPress installation</em>
is_wordpress() {
    local wp_path=$1
    &#91; -f "${wp_path}/wp-config.php" ]
}

<em># Get WordPress version</em>
get_wp_version() {
    local wp_path=$1
    wp core version --path="$wp_path" 2&gt;/dev/null
}

<em># Check if plugin is installed</em>
has_plugin() {
    local wp_path=$1
    local plugin_name=$2
    wp plugin is-installed "$plugin_name" --path="$wp_path" 2&gt;/dev/null
}

<em># Safely update WordPress core</em>
safe_core_update() {
    local wp_path=$1

    if ! is_wordpress "$wp_path"; then
        log_error "Not a WordPress installation: ${wp_path}"
        return 1
    fi

    local current_version=$(get_wp_version "$wp_path")
    log_info "Current version: ${current_version}"

    <em># Backup first</em>
    log_info "Creating backup..."
    local backup_file="/tmp/wp-backup-$(date +%s).sql"
    if ! wp db export "$backup_file" --path="$wp_path" --quiet; then
        log_error "Backup failed"
        return 1
    fi

    <em># Update</em>
    log_info "Updating WordPress core..."
    if wp core update --path="$wp_path"; then
        local new_version=$(get_wp_version "$wp_path")
        log_info "Updated from ${current_version} to ${new_version}"
        rm -f "$backup_file"
        return 0
    else
        log_error "Update failed. Backup saved at: ${backup_file}"
        return 1
    fi
}
</code></pre>



<h4 class="wp-block-heading" id="using-the-library">Using the Library</h4>



<p>Create a script that sources the library:</p>



<pre class="wp-block-code"><code>#!/bin/bash
<em># my-script.sh</em>

<em># Load function library</em>
source ~/wp-functions.sh

<em># Use the functions</em>
log_info "Starting WordPress maintenance..."

if is_wordpress /var/www/html; then
    log_info "WordPress found"
    safe_core_update /var/www/html
else
    log_error "WordPress not found"
    exit 1
fi
</code></pre>



<p>This approach keeps your scripts clean and maintainable. Update the library once, and all scripts benefit.</p>



<h3 class="wp-block-heading" id="advanced-patterns-advanced-patterns">Advanced Patterns {#advanced-patterns}</h3>



<h4 class="wp-block-heading" id="pattern-1-functions-with-named-parameters">Pattern 1: Functions with Named Parameters</h4>



<pre class="wp-block-code"><code>backup_wordpress() {
    <em># Parse named parameters</em>
    local wp_path=""
    local backup_dir=""
    local include_uploads=true

    while &#91;&#91; $# -gt 0 ]]; do
        case $1 in
            --path)
                wp_path="$2"
                shift 2
                ;;
            --backup-dir)
                backup_dir="$2"
                shift 2
                ;;
            --no-uploads)
                include_uploads=false
                shift
                ;;
            *)
                echo "Unknown option: $1" &gt;&amp;2
                return 1
                ;;
        esac
    done

    <em># Use the parameters</em>
    echo "Path: ${wp_path}"
    echo "Backup dir: ${backup_dir}"
    echo "Include uploads: ${include_uploads}"
}

<em># Usage</em>
backup_wordpress --path /var/www/html --backup-dir /backups --no-uploads
</code></pre>



<h4 class="wp-block-heading" id="pattern-2-functions-with-default-parameters">Pattern 2: Functions with Default Parameters</h4>



<pre class="wp-block-code"><code>update_wordpress() {
    local wp_path=${1:-/var/www/html}  <em># Default to /var/www/html</em>
    local backup=${2:-yes}               <em># Default to yes</em>

    echo "Path: ${wp_path}"
    echo "Backup: ${backup}"
}

<em># Call with defaults</em>
update_wordpress

<em># Call with custom values</em>
update_wordpress /var/www/mysite no
</code></pre>



<h4 class="wp-block-heading" id="pattern-3-array-return-values">Pattern 3: Array Return Values</h4>



<pre class="wp-block-code"><code>get_outdated_plugins() {
    local wp_path=$1
    wp plugin list --update=available --path="$wp_path" --field=name
}

<em># Capture into array</em>
mapfile -t plugins &lt; &lt;(get_outdated_plugins /var/www/html)

<em># Loop through results</em>
for plugin in "${plugins&#91;@]}"; do
    echo "Outdated: ${plugin}"
done
</code></pre>



<h3 class="wp-block-heading" id="testing-your-functions-testing">Testing Your Functions {#testing}</h3>



<p>Always test functions before using in production.</p>



<h4 class="wp-block-heading" id="manual-testing-script">Manual Testing Script</h4>



<pre class="wp-block-code"><code>#!/bin/bash
<em># test-functions.sh</em>

source ~/wp-functions.sh

echo "Testing WordPress functions..."
echo "=============================="

<em># Test 1: is_wordpress</em>
echo "Test 1: is_wordpress"
if is_wordpress /var/www/html; then
    echo "✓ PASS"
else
    echo "✗ FAIL"
fi

<em># Test 2: get_wp_version</em>
echo "Test 2: get_wp_version"
version=$(get_wp_version /var/www/html)
if &#91; -n "$version" ]; then
    echo "✓ PASS: Version ${version}"
else
    echo "✗ FAIL"
fi

<em># Add more tests...</em>
</code></pre>



<h4 class="wp-block-heading" id="automated-testing-with-bats">Automated Testing with BATS</h4>



<p>For serious projects, use&nbsp;<a href="https://github.com/bats-core/bats-core">BATS (Bash Automated Testing System)</a>:</p>



<pre class="wp-block-code"><code><em># Install BATS</em>
git clone https://github.com/bats-core/bats-core.git
cd bats-core
./install.sh /usr/local

<em># Create test file: test-wp-functions.bats</em>
<em>#!/usr/bin/env bats</em>

load ~/wp-functions.sh

@test "is_wordpress returns true for valid path" {
    run is_wordpress /var/www/html
    &#91; "$status" -eq 0 ]
}

@test "is_wordpress returns false for invalid path" {
    run is_wordpress /tmp
    &#91; "$status" -eq 1 ]
}

<em># Run tests</em>
bats test-wp-functions.bats
</code></pre>



<h3 class="wp-block-heading" id="next-steps-next-steps">Next Steps</h3>



<p>You now know how to write reusable Bash functions for WordPress automation. Here&#8217;s what to learn next:</p>



<h4 class="wp-block-heading" id="related-guides">Related Guides</h4>



<ol class="wp-block-list">
<li><strong><a href="#">Bulletproof Error Handling in Bash Scripts for WP-CLI</a></strong> &#8211; Take error handling to the next level</li>



<li><strong><a href="#">How to Parse Command Line Arguments in WP-CLI Bash Scripts</a></strong> &#8211; Make your functions accept complex parameters</li>



<li><strong><a href="https://file+.vscode-resource.vscode-cdn.net/blog/logging-debugging-wpcli-automation">Professional Logging and Debugging for WP-CLI Automation Scripts</a></strong>&nbsp;&#8211; Add production-grade logging</li>
</ol>



<h4 class="wp-block-heading" id="practice-projects">Practice Projects</h4>



<p><strong>Build a function library</strong>&nbsp;with these functions:</p>



<ul class="wp-block-list">
<li>Database backup and restore</li>



<li>Plugin/theme management</li>



<li>User management</li>



<li>Content import/export</li>



<li>Security hardening</li>
</ul>



<p><strong>Create a WordPress maintenance script</strong>&nbsp;that:</p>



<ul class="wp-block-list">
<li>Uses multiple functions from your library</li>



<li>Accepts command-line arguments</li>



<li>Has proper error handling</li>



<li>Outputs colored logs</li>
</ul>



<h4 class="wp-block-heading" id="join-wpcli-mastery">Join WPCLI Mastery</h4>



<p>Want to master WordPress automation with battle-tested patterns and real-world projects?</p>



<p><strong><a href="/#pricing">Join the WPCLI Mastery waitlist</a></strong> and get:</p>



<ul class="wp-block-list">
<li>Free WordPress backup automation script (production-ready functions included)</li>



<li>Access to complete function library</li>



<li>Early bird course pricing ($99 vs $199)</li>
</ul>



<h3 class="wp-block-heading" id="conclusion">Conclusion</h3>



<p>Bash functions transform messy WordPress automation scripts into clean, maintainable, professional code. The patterns you learned here—parameter validation, error handling, return values—are the foundation of production-ready automation.</p>



<p><strong>Key takeaways:</strong></p>



<ul class="wp-block-list">
<li>Functions eliminate code duplication</li>



<li>Always validate parameters</li>



<li>Use return codes (0 = success, 1+ = failure)</li>



<li>Handle errors explicitly</li>



<li>Build a reusable function library</li>



<li>Test your functions before production use</li>
</ul>



<p>Start building your function library today. Every reusable function you write saves time on every future script.</p>



<p><strong>Ready to build advanced WordPress automation?</strong> Check out our guide on <a href="#">automating WordPress backups with WP-CLI</a>, which uses these function patterns in a complete project.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p><strong>Questions about Bash functions for WordPress?</strong>&nbsp;Drop a comment below!</p>



<p><strong>Found this helpful?</strong>&nbsp;Share it with other WordPress developers learning automation.</p>
<p>The post <a href="https://wpclimastery.com/blog/writing-reusable-bash-functions-for-wordpress-automation/">Writing Reusable Bash Functions for WordPress Automation</a> appeared first on <a href="https://wpclimastery.com">WP-CLI Mastery</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://wpclimastery.com/blog/writing-reusable-bash-functions-for-wordpress-automation/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
