Using WP CLI to run Cron jobs on multisite networks
Published January 29th, 2017 under Misc
Note: this code appears to have some problems based on feedback here in the comments. It worked fine for me when I used it though.
If you are running your own web server, one of the best ways to run basic administration tasks in WordPress is via the WP CLI (WordPress Command Line Interface). And if you are running your own web server, then it is smart to turn off the default WP Cron systems and using a server level Cron job instead. Tom McFarlin wrote one of the goto blog posts regarding setting this up, but his post doesn’t take the next step of incorporating WP CLI for handling this, and it doesn’t handle WordPress multisites very well, as his code requires adding new Cron tasks whenever a new site is added.
To work around these issues, I wrote the following simple bash script. It grabs a list of all sites on the multisite network via WP CLI, then loops through them all and runs all the due WP Cron tasks for each individual site. To use this, just change the PATH_TO_WORDPRESS
to show the correct path to your WordPress installation.
#!/bin/bash clear PATH_TO_WORDPRESS="/var/www/public_html" for URL in $(wp site list --fields=url --format=csv --path="$PATH_TO_WORDPRESS") do if [[ $URL == "http"* ]]; then wp cron event run --all --due-now --url="$URL" --path="$PATH_TO_WORDPRESS" fi done
To make this run every hour, just add something like this to your Cronjob (where /var/www/wp-cron.sh is the location of your bash script):
@hourly bash /var/www/wp-cron.sh
Feel free to adapt this for your own needs, and to publish any changes. You can consider this public domain content, but a link back to this post is always appreciated 🙂
Anh Tran says:
I’ve never used the cron command of WP-CLI. This is a creative usage of that. Thanks for sharing.
January 30, 2017 at 7:26 am # //
Dustin Holden says:
Thanks. This feels a lot cleaner than using wget or one of the various other hackish methods.
March 6, 2018 at 4:39 am # //
Erfan Ilyas says:
Thank you so much, I was pulling all my hairs and was about go full on bald and then I found your post.
One of the most simple and sophisticated solution.
Thanks again for sharing.
December 21, 2018 at 12:55 pm # //
Ryan Hellyer says:
Glad to hear you find it useful. Perhaps if I’d figured it out earlier, I wouldn’t be bald.
December 21, 2018 at 3:06 pm # //
Ulrich says:
By getting the list of url with: `wp site list –field=url` you can remove the check `$URL == “http”*` and make the command shorter.
January 8, 2019 at 7:55 pm # //
Andy says:
This is a really handy idea, thanks. A couple of improvements I might suggest:
Using –field=url rather than –fields=url would mean you don\’t need the –format=csv option or the if check as it\’ll just return a list of URLs without a heading row.
Adding –deleted=0 –archived=0 to the wp site list command might be preferable, to save running jobs on deleted and archived sites.
February 25, 2019 at 10:58 am # //
Tobsen says:
Thanks for sharing!
May 12, 2020 at 7:04 am # //
Scott N says:
I think what everyone is saying is that this would work best?
#!/bin/bash
clear
PATH_TO_WORDPRESS=”/home/applscom/public_html”
for URL in = $(wp site list –field=url –path=”$PATH_TO_WORDPRESS”)
do
wp cron event run –all –due-now –url=”$URL” –path=”$PATH_TO_WORDPRESS”
fi
done
April 14, 2021 at 10:01 pm # //
Jason says:
When testing I get output:
wordpress-cron.sh: line 15: syntax error near unexpected token `fi’
wordpress-cron.sh: line 15: `fi’
March 22, 2023 at 3:50 pm # //
Ryan Hellyer says:
I think you may have copy/pasted something wrong. It works fine for me.
There was an errant = sign in there which was not required, but it also worked fine with that in there (it’s fixed in the post above now).
July 8, 2023 at 9:15 am # //