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:
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:
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+----+--------------+-------------+
| ID | post_title | post_status |
+----+--------------+-------------+
| 1 | Hello world! | publish |
+----+--------------+-------------+
Hello world!
1
My WordPress SiteChoosing 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.
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_nameID,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:
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_title4
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:
wp eval 'echo get_bloginfo( "name" ), " has ", wp_count_posts()->publish, " published post(s)\n";'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:
wp db tableswp_commentmeta
wp_comments
wp_links
wp_options
wp_postmeta
wp_posts
wp_term_relationships
wp_term_taxonomy
wp_termmeta
wp_terms
wp_usermeta
wp_usersOther 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:
wp search-replace "Fresh bread" "Fresh bread and cakes" --dry-run --report-changed-only+------------+--------------+--------------+------+
| 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:
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 siteurlfirst. - Running search-replace without
--dry-runor 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
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.