If you build any kind of WordPress maintenance automation, sooner or later you hit a wall the official WP-CLI install instructions don’t warn you about. The setup is supposed to be simple — drop one file onto the server and make it usable as a command — yet on shared hosting it fails in a different way on every host.
This article summarizes what we learned by running a read-only SSH-based diagnostic across four shared hosts — ConoHa WING, Xserver, Sakura Internet, and Heteml — to find out what really separates “WP-CLI runs” from “WP-CLI fails to start.”
The “one-liner install” assumption breaks early
The official WP-CLI install snippet looks like this:
curl -O https://raw.githubusercontent.com/wp-cli/wp-cli/v2.12.0/phar/wp-cli.phar
chmod +x wp-cli.phar
sudo mv wp-cli.phar /usr/local/bin/wp
wp --info
In order: download the WP-CLI binary (a single-file executable in PHAR format), mark it executable with chmod +x, move it into /usr/local/bin/ (a directory available to all users) using sudo to gain administrator privileges, then verify the install.
On shared hosting, this sequence does not run as written. sudo (the mechanism that escalates a command to administrator privileges) is generally unavailable, and /usr/local/bin/ is typically read-only by design. The fallback is to use your own home directory — ~/bin/, where ~ is shorthand for the home directory — but that, too, fails on some hosts.
What changes from host to host: whether ~/bin is on PATH (the environment variable that lets you run a command by name alone), whether php itself is on that PATH, whether the PHAR’s first line — its shebang, the #!/usr/bin/env php that says “use the php interpreter” — can resolve, whether the default login shell is bash or csh, and which checksum tools exist.
A read-only diagnostic across four hosts
To avoid leaving any side effects on each host, the diagnostic was a POSIX shell script that only runs which wp (resolves the actual path of the wp command), command -v php (same for php), file probes, and a single write-permission test ($HOME/.wpmm_diag_test_$$, a temp file with the shell’s PID, created and deleted in one breath). Thirteen observation points across four hosts produced this matrix:
| Observation | ConoHa | Xserver | Sakura | Heteml |
|---|---|---|---|---|
which wp |
~/bin/wp (in PATH) |
/usr/bin/wp |
/usr/local/bin/wp |
none |
System wp |
(none) | root-owned PHAR | 70-byte shell wrapper | (none) |
which php |
/usr/bin/php |
/usr/bin/php |
/usr/local/bin/php |
none |
| Default shell | bash | bash | csh | bash |
~/bin on PATH |
yes | no | yes | no |
| Hash tools | md5sum sha1sum |
md5sum sha1sum |
md5 shasum (BSD) |
md5sum only |
file command |
yes | yes | yes | no |
Four hosts, four architectures. The simple act of starting WP-CLI requires a different recipe on each.
Four hosts, four architectures
ConoHa WING — bring-your-own ~/bin/wp
No system-wide WP-CLI is shipped. ~/bin/ exists by default and is on PATH, so dropping a PHAR there is enough to get wp working as a bare command.
One subtle gotcha: a PHAR uploaded through the control panel’s web file manager can refuse to start with a broken signature error, even though the file appears to have arrived intact. We saw this happen multiple times in real environments. The cause is that the upload path can quietly rewrite bytes mid-transit (line-ending conversion, text-mode handling, and the like). The file size and even the MD5 checksum (a short string used to confirm two files have identical contents) match the source — yet the PHAR’s own self-integrity check still flags it as corrupted at startup. Downloading directly into the server over SSH (using the curl command) bypasses the upload path entirely and avoids this rewrite for sure.
Xserver — system-wide preinstall
/usr/bin/wp ships with a root-owned PHAR by default. Timestamps suggest a 2023 build — somewhat dated, but which wp resolves immediately, and no extra setup is required.
Sakura Internet — shell-wrapper approach
/usr/local/bin/wp is a small 70-byte shell-script wrapper — a short program that sits in front of the real binary and selects the right PHP runtime to launch it with. Calling wp runs that wrapper, which in turn picks an appropriate PHP and starts the actual WP-CLI for you. wp works as a bare command.
What does need attention: Sakura uses FreeBSD rather than Linux, which differs in subtle ways. The default login shell is csh instead of the more common bash, and the checksum tool is the BSD-flavored md5 rather than md5sum. Automation scripts written for Linux won’t run as-is — they need to be rewritten in plain POSIX sh, the lowest common denominator across UNIX-style systems, and bash-only constructs ([[ ]], brace expansion, process substitution) need to be removed.
Heteml — php not on PATH
This is the trickiest one. ~/bin/ exists and you can place a PHAR there, but which php returns nothing. Looking inside /usr/local/bin/ you find versioned aliases like php8.3 — but no bare php.
The first line of the WP-CLI PHAR is the shebang mentioned earlier — #!/usr/bin/env php, which says “look up php on PATH and run me with that.” On Heteml that lookup fails, and so direct execution of the PHAR fails. Instead, you have to invoke a specific PHP binary explicitly (the versioned full path, like php8.3) and hand it the PHAR:
/usr/local/bin/php8.3 ~/bin/wp --info
In other words, on Heteml the WP-CLI command registered with the automation tool can’t be just wp. It has to be a single line that pairs the absolute path to a versioned PHP binary with the path to the WP-CLI PHAR, separated by a space — concretely, something like /usr/local/bin/php8.3 ~/bin/wp.
A four-step detection flow
To absorb the four architectures with one piece of logic, ordering the checks by likelihood works well:
Step 1: which wp resolves → wp_cli_path = "wp"
Step 2: ~/bin/wp runs directly → wp_cli_path = "~/bin/wp"
Step 3: ~/bin/wp exists but no php on PATH
→ find a versioned php's full path and combine
→ wp_cli_path = "<php full path> ~/bin/wp"
Step 4: none of the above → install candidate
Step 1 covers most cases (ConoHa, Xserver, Sakura), Step 3 rescues Heteml-style hosts, and only Step 4 requires fresh installation. At every step, wp --info is run and both its exit status (the number a command returns to indicate success or failure — 0 means success) and its output are inspected. The final “this works” verdict comes from a successful wp --info, never from a hash.
That last point matters: in this investigation we observed cases where two PHAR files had identical MD5 hashes but one would still fail with broken signature at runtime. Hash equality says only “the bytes are the same” — it doesn’t say “this PHAR will execute.” Treat the hash as a tamper check, not a health check.
Takeaway — observe, propose, verify
“WP-CLI doesn’t work on this host” is rarely a one-off accident. Usually it’s that the configuration in use doesn’t match the host’s underlying architecture.
Rather than trying to enumerate every host’s quirks in advance, a more practical approach is to observe the host over a read-only SSH session and propose the most likely configuration with a confidence label — high / medium / low — and let the operator confirm. The actual “this is healthy” verdict still comes from wp --info on the proposed path, with no write-side effects until the operator agrees.
Shared hosts will keep being diverse, and that diversity is itself the constraint. Building maintenance tooling that respects it — observe, propose, verify, in that order — is what keeps the work safe, traceable, and reproducible.