Managing and batch updating multiple WordPress sites from the terminal with wp-cli
Back to blog

Managing and batch updating multiple WordPress sites from the terminal with wp-cli

6/7/2026 · 2 min · WordPress

Managing and batch updating multiple WordPress sites from the terminal with wp-cli#

Anyone managing multiple WordPress installations knows how tedious routine maintenance can be: opening dozens of browser tabs, logging into separate /wp-admin dashboards, clicking update on plugins, and hoping nothing crashes.

Using WP-CLI over SSH replaces this manual clicking. With it, you create users, update plugins, run database backups, and execute search-and-replace queries in seconds.

Here is a practical guide covering secure installation (with or without root privileges), safe credential workflows, and a batch Bash script to update all sites on a server.

1. Prerequisites and PHP CLI checks#

Before downloading the binary, make sure PHP CLI is installed and running:

# Verify PHP CLI version
php --version

If the command is not found, install PHP CLI and standard extensions:

# Debian / Ubuntu
sudo apt-get update
sudo apt-get install php-cli php-mysql php-xml php-mbstring php-curl -y

# RHEL / Rocky Linux / AlmaLinux
sudo dnf install php-cli php-mysqlnd php-xml php-mbstring php-curl -y

2. Global installation with root access#

To make wp accessible system-wide:

# 1. Download official PHAR binary
curl -sO https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar

# 2. Validate integrity with SHA-256
curl -sLO https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar.sha256 && shasum -a 256 -c wp-cli.phar.sha256

# 3. Make executable and move to global PATH
chmod +x wp-cli.phar
sudo mv wp-cli.phar /usr/local/bin/wp

# 4. Verify installation
wp --info

3. Local installation on shared hosting without root#

In jailed shell environments or shared hosting accounts:

# 1. Create personal bin directory
mkdir -p ~/bin
curl -sO https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
chmod +x wp-cli.phar
mv wp-cli.phar ~/bin/wp

# 2. Add to PATH in ~/.bashrc
echo 'export PATH="$HOME/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc

4. The danger of plaintext passwords in CLI arguments#

Safe ways to manage passwords:#

# Option 1: Set password interactively via prompt (never written to history)
wp user update 1 --prompt=user_pass --skip-email

# Option 2: Let WP-CLI generate a secure random password
wp user create new-admin admin@yourdomain.com --role=administrator

# Option 3: Use temporary environment variables
export WP_PASS="TemporaryPassword123!"
wp user create new-admin admin@yourdomain.com --role=administrator --user_pass="$WP_PASS"
unset WP_PASS

5. Fast backups streaming into gzip#

Before updating themes or plugins, create a compressed database snapshot:

# Export database directly through gzip (saves disk I/O and storage)
wp db export - | gzip > backup-$(date +%Y%m%d-%H%M%S).sql.gz

# Restore compressed dump
gunzip -c backup-XXXX.sql.gz | wp db import -

# Optimize and repair tables
wp db optimize
wp db repair

6. Daily operational commands#

A. Core updates and checksum verification#

# Check available updates
wp core check-update
wp plugin list --update=available
wp theme list --update=available

# Update all plugins and themes
wp plugin update --all
wp theme update --all

# Audit WordPress core integrity against official checksums
wp core verify-checksums

B. Migrations and search-and-replace#

# 1. Preview changes with dry-run
wp search-replace 'https://old-site.com' 'https://new-site.com' --all-tables --dry-run

# 2. Execute replacements across all tables
wp search-replace 'https://old-site.com' 'https://new-site.com' --all-tables

C. Cache flushing#

# Clear transients and object cache
wp transient delete --all
wp cache flush

7. Defining project defaults in wp-cli.yml#

Create a wp-cli.yml in your project root to disable destructive commands and configure shortcuts:

path: /var/www/site/public_html
disabled_commands:
  - db drop
  - db reset
skip-plugins:
  - akismet

8. Managing WordPress multi-site networks#

# List network subsites
wp site list

# Update core and plugins across the network
wp core update --network
wp plugin update --all --network

9. Batch Bash script for multi-site servers#

If you manage a server with multiple client sites, this script discovers all WordPress directories, creates backups, and updates plugins with logging:

#!/usr/bin/env bash
set -euo pipefail

BASE_DIR="${1:-/home}"
LOG_FILE="/var/log/wp-update-$(date +%Y%m%d-%H%M%S).log"
BACKUP_DIR="/root/wp-backups/$(date +%Y%m%d)"
mkdir -p "$BACKUP_DIR"

log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"; }

SITES=$(find "$BASE_DIR" -maxdepth 5 -name wp-config.php -not -path "*/wp-content/*" 2>/dev/null)

for wpconfig in $SITES; do
    site=$(dirname "$wpconfig")
    SITE_NAME=$(basename "$(dirname "$site")")
    log "Updating site: $site"
    
    # 1. Database backup
    wp --path="$site" --no-color --skip-plugins db export "$BACKUP_DIR/${SITE_NAME}-pre-update.sql" --quiet 2>/dev/null || true
    
    # 2. Update core and plugins
    wp --path="$site" --no-color core update --skip-plugins --quiet || true
    wp --path="$site" --no-color plugin update --all --quiet || true
    
    # 3. Verify checksums
    wp --path="$site" --no-color core verify-checksums --quiet || log "Checksum alert on $site"
done
log "Batch update routine finished."

Practical production takeaways#

  1. Use --skip-plugins during crashes: If an update causes a fatal 500 error, WP-CLI still runs when passing --skip-plugins, allowing you to deactivate the broken plugin directly.
  2. Pipes save time and storage: Piping dumps directly through gzip prevents creating giant uncompressed .sql files on your disk.
  3. Audit checksums periodically: Running wp core verify-checksums is the fastest method to verify that core WordPress files have not been modified or infected.
  4. Secure admin surfaces: Pair CLI operations with a thorough WordPress technical security audit and verify web server permissions with our Nginx cache permissions guide.

Was this article helpful?

Leave a quick reaction to help prioritize future technical guides:

CC BY-NC

This post is licensed under CC BY-NC.

Comments

Join the discussion below.

0 comments