One of the drawbacks of WP Engine’s implementations of SSH is the time it takes to create the SSH tunnel. While this has gotten significantly better it’s still slow enough that you really should avoid creating lots of individual connections. While that’s fine for running single long commands, you’ll need to get creative if you want to run a bunch of short commands. To explain have a look at these examples taken from my toolkit.
time captaincore ssh anchorhost1 "wp plugin list"
0.09s user 0.08s system 2% cpu 8.676 total
time captaincore ssh anchorhost1 "wp theme list"
0.09s user 0.06s system 2% cpu 7.114 total
time captaincore ssh anchorhost1 "wp core version"
0.09s user 0.06s system 2% cpu 5.614 total
Separating these commands takes a total of 21.404 seconds. Now if we combine them into a single SSH connection we see it reduces down to 12.181 seconds.
time captaincore ssh anchorhost1 "wp plugin list; wp theme list; wp core version"
0.10s user 0.07s system 1% cpu 12.181 total
That’s a 9 second difference. Ok so 9 seconds might not seem like much however let’s imagine this is part of a daily script. Then let’s assume this is run on 1000 websites. Now that 9 seconds becomes 2.5hr of wasted time per day just connecting to SSH 9 seconds * 1000 sites / 60 convert to minutes / 60 convert to hours = 2.5hr/day
.
Using bash to grab all of the details from one single SSH connection then parse the results
The following will store results from multiple commands to a bash variable $response
. The trick is to echo spaces between each result so that in bash we can parse the results by the line breaks. The arguments --skip-themes --skip-plugins --skip-packages
help speed up WP-CLI as we can talk directly to WordPress.
response=$( captaincore ssh $website 'wp plugin list --format=json --skip-themes --skip-plugins --skip-packages --fields=name,title,status,version; echo ""; wp theme list --format=json --skip-themes --skip-plugins --skip-packages --fields=name,title,status,version; echo ""; wp core version --skip-themes --skip-plugins --skip-packages' )
IFS=$'\n' read -rd '' -a response_parsed <<<"$response"
plugin_data=${response_parsed[0]}
theme_data=${response_parsed[1]}
core_version=${response_parsed[2]}
echo $plugin_data
echo $theme_data
echo $core_version