Himanshu SharmaSoftware engineer
Let’s talk

WordPress · Lesson 16 of 45

Managing WordPress with WP-CLI

Use WP-CLI, the official WordPress command-line tool, to manage posts, users, options, plugins and the database quickly, with output formats and scripts.

13 minWP-CLI and workflowUpdated 23 October 2026

By the end of this lessonRun everyday WP-CLI commands, read and change data safely, get output in the format you need, and script repetitive jobs.

What WP-CLI is

WP-CLI is the official command-line interface for WordPress. Anything you do in the dashboard, and much more, can be done by typing a command. It is faster for repetitive jobs, works over SSH on servers where the dashboard is slow, and can be put in scripts.

Install it from wp-cli.org (it is a single PHP file, wp-cli.phar, that you make executable and rename to wp). Many hosts and local tools such as Local already include it. Run commands inside your WordPress folder, or add --path=/path/to/site.

Every command follows the same shape:

bash
wp <command> <subcommand> [arguments] [--options]

For example wp plugin activate hello or wp user create sam sam@example.com --role=author. wp help, wp help post and wp help post create explain every command and option.

Reading data

List, get and count things:

bash
wp post list --fields=ID,post_title,post_status
wp post get 1 --field=post_title
wp user list --format=count
wp option get blogname
result
+----+--------------+-------------+
| ID | post_title   | post_status |
+----+--------------+-------------+
| 1  | Hello world! | publish     |
+----+--------------+-------------+
Hello world!
1
My WordPress Site

Choosing the output format

Most list commands accept --format:

  • table (the default in a terminal), csv, json, yaml;
  • ids: just the IDs, ready to pass to another command;
  • count: just the number.
bash
wp post list --post_type=page --post_status=any --format=csv --fields=ID,post_title,post_status
wp post list --post_type=page --post_status=any --format=ids
wp post list --post_type=page --post_status=any --format=json --fields=ID,post_name
result
ID,post_title,post_status
3,"Privacy Policy",draft
2,"Sample Page",publish
3 2
[{"ID":3,"post_name":"privacy-policy"},{"ID":2,"post_name":"sample-page"}]

--fields picks the columns; --field (singular) prints the value of just one.

Changing data

Create, update and delete:

bash
wp post create --post_type=page --post_title="Contact" --post_status=publish --porcelain
wp post update 2 --post_title="About us"
wp option update blogdescription "Fresh bread every morning"
wp post delete 3 --force
wp post list --post_type=page --post_status=any --fields=ID,post_title
result
4
Success: Updated post 2.
Success: Updated 'blogdescription' option.
Success: Deleted post 3.
+----+------------+
| ID | post_title |
+----+------------+
| 4  | Contact    |
| 2  | About us   |
+----+------------+

--porcelain makes create print only the new ID, useful in scripts. wp post delete 3 would move the privacy policy draft to the trash; --force deletes it permanently. Commands that change data take effect immediately: there is no "Save" step and no undo, so double-check before running them on a live site.

Running code

wp eval runs a line of PHP inside WordPress, with every WordPress function available; wp eval-file runs a whole PHP file. Many examples in this course are exactly that:

bash
wp eval 'echo get_bloginfo( "name" ), " has ", wp_count_posts()->publish, " published post(s)\n";'
result
My WordPress Site has 1 published post(s)

wp shell opens an interactive PHP prompt inside WordPress, handy for exploring.

The database

WP-CLI talks to the database using the details in wp-config.php. wp db tables lists the WordPress tables, using the real table prefix:

bash
wp db tables
result
wp_commentmeta
wp_comments
wp_links
wp_options
wp_postmeta
wp_posts
wp_term_relationships
wp_term_taxonomy
wp_termmeta
wp_terms
wp_usermeta
wp_users

Other useful database commands:

  • wp db export backup.sql: a full SQL dump, the quickest backup there is;
  • wp db import backup.sql: restore it;
  • wp db query "SELECT ...": run SQL;
  • wp db optimize, wp db check.

Search and replace

wp search-replace changes text everywhere in the database, and it correctly handles serialized PHP data (where a plain SQL replace would corrupt the stored lengths). Always look first with --dry-run:

bash
wp search-replace "Fresh bread" "Fresh bread and cakes" --dry-run --report-changed-only
result
+------------+--------------+--------------+------+
| Table      | Column       | Replacements | Type |
+------------+--------------+--------------+------+
| wp_options | option_value | 1            | PHP  |
+------------+--------------+--------------+------+
Success: 1 replacement to be made.

The next lesson uses it to move a site between addresses.

Plugins, themes, core and maintenance

You have already met wp plugin and wp theme. Others you will use often:

Command Does
wp core version, wp core update show or update the WordPress version
wp plugin update --all update every plugin
wp cache flush clear the object cache
wp transient delete --all delete cached transients
wp cron event list list scheduled tasks
wp rewrite flush rebuild permalink rules
wp media regenerate recreate image sizes after changing them
wp maintenance-mode activate show a maintenance message to visitors

Scripting

Because output formats are predictable, commands combine well. For example, to trash every draft post older than a year, in a Bash shell:

bash
wp post delete $(wp post list --post_status=draft --date_query='[{"before":"1 year ago"}]' --format=ids)

On a real server, you can also run commands against a remote site over SSH with --ssh=user@host/path/to/site, or define aliases for your sites in a wp-cli.yml file so that wp @live plugin list works from your computer.

Common mistakes

  • Running a destructive command on the wrong site. Check wp option get siteurl first.
  • Running search-replace without --dry-run or without a backup.
  • Using SQL REPLACE() for URLs, which breaks serialized data.
  • Running WP-CLI as the root user on a server, which can leave files owned by root; WP-CLI warns about this.

Exercise

With WP-CLI: create three draft posts titled "Draft 1" to "Draft 3", list only the IDs of draft posts, then publish one of them by ID.

Show one possible answer
bash
wp post create --post_title="Draft 1" --post_status=draft
wp post create --post_title="Draft 2" --post_status=draft
wp post create --post_title="Draft 3" --post_status=draft
wp post list --post_status=draft --format=ids
wp post update <one of those IDs> --post_status=publish

--format=ids prints something like 6 5 4; publishing one makes it appear on the blog straight away.

Key points

  • WP-CLI runs WordPress from the terminal: wp <command> <subcommand> [arguments] [--options].
  • Commands cover posts, users, options, plugins, themes, the database, cron, cache and more; wp help explains each one.
  • --format=table|csv|json|ids|count and --fields choose what you get back, which makes output easy to script.
  • wp search-replace and wp db export make site moves and backups fast, and --dry-run shows changes before making them.

Check yourself

1. Which command lists all published pages with their IDs and titles?
2. What does --format=ids output?
3. What does --dry-run do on wp search-replace?
4. How do you run WP-CLI against a site in another folder?