#!/bin/bash # # Wrapper script for WP-CLI's search-replace command. # Safely runs 'wp search-replace' with the correct user and path context. # # --- Configuration --- set -e set -u set -o pipefail # Colors for output messages RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # --- Default Values --- WP_ROOT="/var/www/webroot/ROOT" # Default WordPress root directory WEB_USER="litespeed" # Default web server user WP_CLI_PATH="/usr/local/bin/wp" # Default path to WP-CLI # --- Helper Functions --- # Print informational messages info() { printf "${BLUE}[INFO] %s${NC}\n" "$@" } # Print success messages success() { printf "${GREEN}[SUCCESS] %s${NC}\n" "$@" } # Print warning messages warning() { printf "${YELLOW}[WARNING] %s${NC}\n" "$@" } # Print error messages and exit error_exit() { printf "${RED}[ERROR] %s${NC}\n" "$@" >&2 exit 1 } # Function to display usage information usage() { printf "Usage: %s [options...]\n" "$0" printf "\n" printf "A wrapper for the 'wp search-replace' command that automatically handles user and path context.\n" printf "All options after are passed directly to 'wp search-replace'.\n" printf "\n" printf "Required Arguments:\n" printf " The string to search for.\n" printf " The string to replace it with.\n" printf "\n" printf "Common WP-CLI Options (pass these after ):\n" printf " [...] One or more database tables to restrict the search to.\n" printf " --dry-run Run the search-replace without making any changes.\n" printf " --all-tables Search through all tables registered to \$wpdb.\n" printf " --network Search and replace through all sites in a multisite network.\n" printf " --recurse-objects Enable recursing into objects to replace strings.\n" printf " --report-changed-only Only report changes, not every table checked.\n" printf " --skip-columns= Comma-separated list of columns to skip.\n" printf "\n" printf "Wrapper-Specific Options:\n" printf " --wproot=PATH Override the default WordPress root directory (%s).\n" "$WP_ROOT" printf " --webuser=USER Override the default web server user (%s).\n" "$WEB_USER" printf " -h, --help Display this help message.\n" printf "\n" printf "Example:\n" printf " %s 'http://old-domain.com' 'https://new-domain.com' --all-tables --dry-run\n" "$0" exit 1 } # --- Argument Parsing --- # Separate wrapper arguments from WP-CLI arguments WP_CLI_ARGS=() while [[ $# -gt 0 ]]; do case "$1" in -h|--help) usage ;; --wproot=*) WP_ROOT="${1#*=}" shift ;; --webuser=*) WEB_USER="${1#*=}" shift ;; *) # Collect all other arguments for WP-CLI WP_CLI_ARGS+=("$1") shift ;; esac done # Check for mandatory arguments if [[ ${#WP_CLI_ARGS[@]} -lt 2 ]]; then error_exit "Missing required and arguments." fi info "Wrapper settings: WP_ROOT='${WP_ROOT}', WEB_USER='${WEB_USER}'" info "Arguments passed to WP-CLI: ${WP_CLI_ARGS[*]}" # --- Prerequisite Checks --- info "Checking prerequisites..." if [[ ! -d "$WP_ROOT" ]]; then error_exit "WordPress root directory '$WP_ROOT' does not exist."; fi if ! command -v "$WP_CLI_PATH" &> /dev/null; then warning "WP-CLI not found at $WP_CLI_PATH." if ! command -v "wp" &> /dev/null; then error_exit "WP-CLI not found at $WP_CLI_PATH or in system PATH. Please install WP-CLI." else WP_CLI_PATH="wp" # Fallback to wp in path info "Found 'wp' in system PATH. Using that." fi fi if ! id "$WEB_USER" &>/dev/null; then error_exit "Web user '$WEB_USER' does not exist."; fi success "Prerequisites seem OK." # --- WP-CLI Execution Context Setup --- # This logic is adapted from install-wordpress.sh to ensure commands run as the correct user. WP_RUN_ARGS=("--path=$WP_ROOT") SUDO_CMD="" WP_EXECUTABLE="$WP_CLI_PATH" if [[ "$(id -u)" -eq 0 ]]; then info "Script is running as root. Attempting to run WP-CLI as '$WEB_USER'." # Use 'sudo -n' to check for passwordless sudo access. if sudo -n -u "$WEB_USER" "$WP_EXECUTABLE" --info --skip-update --quiet "${WP_RUN_ARGS[@]}" &>/dev/null; then SUDO_CMD="sudo -u $WEB_USER" info "WP-CLI will be executed as '$WEB_USER'." else warning "Could not execute WP-CLI as '$WEB_USER' without a password. Falling back to running as root." WP_RUN_ARGS+=("--allow-root") fi else if [[ "$(id -un)" != "$WEB_USER" ]]; then info "Script is running as non-root user '$(id -un)'. Checking for sudo access to run as '$WEB_USER'." if sudo -n -u "$WEB_USER" "$WP_EXECUTABLE" --info --skip-update --quiet "${WP_RUN_ARGS[@]}" &>/dev/null; then SUDO_CMD="sudo -u $WEB_USER" info "Successfully configured sudo execution for WP-CLI as '$WEB_USER'." else error_exit "Unable to execute WP-CLI as '$WEB_USER'. Ensure the current user has passwordless sudo access, or run this script as '$WEB_USER' or 'root'." fi else info "Script is already running as the web user ('$WEB_USER')." fi fi info "WP-CLI final execution command prefix: [${SUDO_CMD:-direct}]" # --- Execute Command --- info "Executing 'wp search-replace'..." # Build command array safely to preserve argument quoting CMD=() if [[ -n "$SUDO_CMD" ]]; then # shellcheck disable=SC2206 CMD=($SUDO_CMD) # split sudo command into array elements fi CMD+=("$WP_EXECUTABLE" "search-replace") CMD+=("${WP_CLI_ARGS[@]}") CMD+=("${WP_RUN_ARGS[@]}") # Run the command and capture exit status "${CMD[@]}" STATUS=$? if [[ $STATUS -eq 0 ]]; then success "'wp search-replace' command completed successfully." # Optional: flush caches to ensure changes propagate info "Flushing WordPress caches (wp cache flush)..." FLUSH_CMD=( ) if [[ -n "$SUDO_CMD" ]]; then # shellcheck disable=SC2206 FLUSH_CMD=($SUDO_CMD) fi FLUSH_CMD+=("$WP_EXECUTABLE" "cache" "flush" "${WP_RUN_ARGS[@]}") "${FLUSH_CMD[@]}" || warning "Cache flush command returned non-zero exit status." else error_exit "The 'wp search-replace' command failed with exit code $STATUS." fi exit $STATUS