Skip to content

How to use WP-CLI to manage a WordPress site

WP-CLI runs WordPress jobs from the server's command line. Connect over SSH, run wp --info to see whether it is installed, and add it if it is not. Then update, back up, repair and inspect the site with short commands, even when the dashboard will not load.

By
WP Ministry
Updated

In short

  • WP-CLI does the dashboard's jobs from the command line, over SSH. Run wp --info to see whether your host has it.
  • Run commands from the folder that holds wp-config.php, as the user that owns the site's files, and never as root.
  • Export the database before any command that writes, and use --dry-run where a command offers it.
  • A command loads the site's plugins and theme unless you add --skip-plugins and --skip-themes.
  • Maintenance mode switched on by a command ends by itself after ten minutes.
  • With no SSH, most of these jobs have a place in the dashboard.

WP-CLI is the command line interface for WordPress. You connect to the server over SSH, type a short command, and it does a job the dashboard would do: an update, a plugin switched off, a new password, a copy of the database. It needs no browser, so it can still work when the dashboard will not load.

Your host may already have installed it. If not, it is one file that you can add yourself. The commands below are grouped by job, with what each prints when it worked.

Find out whether your host has it

WP-CLI is used over SSH, a text connection to the server. Your host's control panel or documentation says whether your plan includes SSH and how to connect. Once you are connected, ask WP-CLI to describe itself:

bash
wp --info

If it is installed, it prints a short list: the operating system, the PHP it uses and, on the last line, the WP-CLI version. If the shell answers that it cannot find the command, WP-CLI is not installed under that name. Ask the host before you add your own copy.

Install it where it is missing

WP-CLI needs PHP 7.2.24 or later, and nothing else beyond what WordPress itself needs. php --version shows what the server has. These are the handbook's steps.

  1. Step 1: Download the file

    bash
    curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
  2. Step 2: Check that it runs

    It prints the same list as wp --info.

    bash
    php wp-cli.phar --info
  3. Step 3: Make it a command

    wp --info now works from any folder.

    bash
    chmod +x wp-cli.phar
    sudo mv wp-cli.phar /usr/local/bin/wp

If your account cannot use sudo, stop after the second step. Leave the file in your home folder and type php ~/wp-cli.phar wherever this page says wp.

The handbook's installing page also shows how to check the download's signature. wp cli update brings WP-CLI itself up to date. To remove it, delete the file.

Four things to know before the first command

  • Where to run it. Run commands from the site's main folder, the one that holds wp-config.php, or add --path=/path/to/site to any command. Away from the site's folders, WP-CLI stops and says "This does not seem to be a WordPress installation."
  • It acts as you. A command has the permissions of the user who typed it. Log in as the user that owns the site's files. Do not use root: the handbook warns that every plugin and theme on the site would then run with full rights over the whole server. WP-CLI refuses to run as root unless you add --allow-root. Leave that flag alone on a live site.
  • It loads the site's code. Unless told otherwise, a command starts WordPress with every active plugin and the theme. A broken plugin then breaks the command too, and on a site you suspect is hacked, the suspect code runs. --skip-plugins and --skip-themes leave them out. Must-use plugins are loaded all the same.
  • There is no undo. Export the database before a command that writes, and use --dry-run where a command has it.

wp help followed by a command's name, as in wp help plugin update, prints that command's options.

Look around

These commands only read. They are a safe way to learn the tool.

bash
wp core version
wp plugin list
wp theme list
wp user list
wp option get siteurl

The first prints the WordPress version number. The plugin and theme lists are tables with a row for each one: its name, whether it is active, whether an update is available, and its version. The name column holds the name that other commands expect. The user list shows each account's ID, login, email, registration date and role. The last command prints the address stored for the site.

Back up before anything that writes

bash
wp db export ~/before-changes.sql

This runs the server's mysqldump with the database name and password already in wp-config.php. It answers "Success: Exported to" and the file's name. The ~/ puts the file in your home folder, not in the site's folder, where it might be reachable from the web. Download it, and delete it from the server when you are done: it holds everything in the database.

To go back, import the same file. Anything added to the site since the export is not in it:

bash
wp db import ~/before-changes.sql

An export is the database only, not the uploads, plugins or themes. How to schedule automatic WordPress backups covers a full backup and how to prove it restores.

Update WordPress, plugins and themes

Look first. These three change nothing:

bash
wp core check-update
wp plugin update --all --dry-run
wp theme update --all --dry-run

The first lists newer WordPress versions, or says the site is up to date. The other two list what would be updated. wp core update has no --dry-run.

Then update:

bash
wp plugin update --all
wp theme update --all
wp core update
wp core update-db

Each ends with a line that begins "Success:", such as "Success: Updated 2 of 2 plugins." or "Success: WordPress updated successfully." The last command runs the database update that a new WordPress version can need.

To go one at a time, put a plugin's name in place of --all. --exclude= followed by names, separated by commas, holds some back. wp core update --minor takes only minor releases. How to safely update WordPress, plugins and themes has the order to work in, what to check afterwards, and how to go back a version.

Install, switch off and remove plugins and themes

bash
wp plugin install plugin-folder-name --activate
wp plugin deactivate plugin-folder-name
wp plugin delete plugin-folder-name
wp theme install theme-folder-name
wp theme activate theme-folder-name
wp theme delete theme-folder-name

install takes a name from WordPress.org, the path to a zip file on the server, or the address of one. Each command reports what it did and ends with a count, such as "Success: Deactivated 1 of 1 plugins."

Two details are easy to miss:

  • wp plugin delete removes the plugin's files and nothing more. wp plugin uninstall runs the plugin's own uninstall procedure first, then deletes the files. It skips an active plugin unless you add --deactivate.
  • wp theme delete refuses the active theme. Activate another one first.

To undo a deactivation, run wp plugin activate with the same name.

Users and passwords

bash
wp user update example-login --user_pass='a-long-new-password'
wp user create new-login person@example.com --role=editor

update names the user by login, email or ID, and answers "Success: Updated user" with the ID. Keep the single quotes around the password. Without them the shell reads a $ and the letters after it as a variable and drops them, and the command can answer "Success" while the old password stays in place. A password typed as part of a command can stay in your shell's history. Write --prompt=user_pass in its place and WP-CLI asks for the password instead. --skip-email stops the notice to the user.

create makes up a password when you give none and prints it once, on a line that begins "Password:". The role is one of administrator, editor, author, contributor or subscriber. --send-email mails the new user their account details.

wp user list --role=administrator shows who has full control. An administrator nobody recognizes is a reason to read how to check whether your WordPress site has been hacked.

Check the database and replace text in it

bash
wp db check
wp db optimize

Both run the server's mysqlcheck. The first checks every table and answers "Success: Database checked." The second rebuilds the tables and answers "Success: Database optimized." How to clean up and optimize a WordPress database says what that is worth and what to clean first.

wp search-replace swaps one piece of text for another in every row of WordPress's tables, and it handles PHP serialized data. Run it with --dry-run first:

bash
wp search-replace 'https://old-example.com' 'https://new-example.com' --skip-columns=guid --dry-run

It reports what it would change and saves nothing. When the report looks right, export the database and run the command again without --dry-run. How to change your WordPress URL has the whole job, including what to do before and after.

bash
wp cache flush
wp transient delete --expired
wp rewrite flush
  • wp cache flush empties WordPress's object cache and answers "Success: The cache was flushed." On a multisite network with a persistent object cache, that is typically every site's cache, and the reference warns of the load on a busy site. Pages stored by a caching plugin, the host or a CDN are cleared with their own controls.
  • wp transient delete --expired removes temporary values that are past their time, and reports how many it removed. It works on the database. On a site with a persistent object cache such as Redis or Memcached, transients are kept there, and this command does not reach them.
  • wp rewrite flush rebuilds WordPress's rewrite rules from the kinds of content now registered, and answers "Success: Rewrite rules flushed." Plugins and the theme register some of those, so do not add the skip flags here. It is the command-line answer to pages that return 404 after a change: see how to fix the WordPress 404 error.

Look at scheduled events

bash
wp cron event list
wp cron event run --due-now

The list shows each event's hook, when it runs next, and how often it repeats. The second command runs every event that is due now and ends with a count of what it ran. An event whose time is long past means nothing is starting WordPress's scheduler: the backups guide shows how to put it on a real clock.

Maintenance mode

bash
wp maintenance-mode activate
wp maintenance-mode status
wp maintenance-mode deactivate

While it is on, visitors get WordPress's own maintenance message and status answers "Maintenance mode is active."

It does not stay on. The command writes the same .maintenance file that an update writes, holding the time it was made, and WordPress ignores that file once it is ten minutes old. For longer work, run wp maintenance-mode activate --force before the ten minutes are up. It writes the file again with the new time.

deactivate is also the fix for a site stuck in maintenance mode after an interrupted update. How to fix "Briefly unavailable for scheduled maintenance" explains why that happens.

Get back into a broken site

When every page shows an error and the dashboard will not load, WP-CLI can still reach the site, as long as it does not load the code that is failing.

  1. Step 1: Check WordPress's own files

    This compares WordPress's files with the checksums WordPress.org publishes. It does not load WordPress, so it is safe to run first. A clean run answers "Success: WordPress installation verifies against checksums." A file that differs gets a warning with its name. A WordPress update went wrong: a runbook covers repairing them.

    bash
    wp core verify-checksums
  2. Step 2: Save the list of active plugins

    Copy the names somewhere. You will need them to switch the plugins back on.

    bash
    wp plugin list --status=active --field=name --skip-plugins --skip-themes
  3. Step 3: Switch every plugin off

    Reload the site. If it loads, a plugin was the cause. Switch them back on with wp plugin activate and a name, one at a time, until the fault returns. How to find and fix a WordPress plugin conflict has a quicker way to narrow it down.

    bash
    wp plugin deactivate --all --skip-plugins --skip-themes
  4. Step 4: Switch to a default theme

    Do this only if the site is still broken with every plugin off. wp theme list --skip-plugins --skip-themes shows what is installed. The default themes have names that begin with "twenty". To undo it, activate the earlier theme by name.

    bash
    wp theme activate default-theme-folder-name --skip-plugins --skip-themes

If WP-CLI itself stops with a database error, the fault is below WordPress: see how to fix "Error establishing a database connection".

If your host offers no SSH

Most of these jobs have a place in the dashboard. Updates are under Dashboard, then Updates. Plugins, themes and users have their own screens. Saving the screen under Settings, then Permalinks rebuilds the rewrite rules. A copy of the database comes from the host's backup tool or its database tool.

What the dashboard cannot do is run when it will not load. For that case, switch the plugins off from outside. How to deactivate WordPress plugins when you are locked out of the dashboard has every way of doing it, least invasive first.

It is also worth asking the host. A host may be willing to run a WP-CLI command for you, or may offer a terminal inside its control panel.

When to get help

Stop and ask if wp core verify-checksums reports changed files that you cannot explain, if a restore fails, or if a command names an error you do not understand on a site that takes orders. Try an unfamiliar command on a staging copy before the live site.

If you would rather not run the upkeep yourself, every WordPress maintenance plan covers weekly updates to WordPress core, plugins and themes, with a visual check afterward and a rollback if something is wrong.

Common questions

Can I undo a WP-CLI command?

Not with a command. Nothing keeps a record to roll back. What brings the earlier state back is the export you made first, with wp db import, or a full backup when files changed as well. That is the reason to export before every command that writes.

Why does WP-CLI refuse to run as root?

Because a command loads the site's plugins and theme, and as root that code would have full rights over the whole server. WP-CLI stops and suggests running the command as the user the site belongs to, in the form sudo -u USER -i -- wp followed by the command. --allow-root overrides the refusal. On a live site, use the site's user.

How do I run a command on one site of a multisite network?

Add --url= with that site's address, as in wp plugin list --url=https://example.com/shop/. In multisite, that flag is how the target site is named. Some commands also take --network to act on every site, such as wp core update-db --network and wp plugin activate plugin-folder-name --network.

A command stops with a PHP error from a plugin. What now?

Add --skip-plugins --skip-themes and run it again. The command then starts WordPress without the plugins and the theme, so their errors cannot stop it. To leave out one plugin only, name it: --skip-plugins=plugin-folder-name.

More on this subject

Not sure what is wrong?

Tell us what you see. We reply with the cause and a fixed quote, and the diagnosis is free.