id (User and Group Identity)
id prints the user and group context for the current process (or a specified user): UID, primary GID, and supplementary groups.
On a WordPress VPS, this is one of the fastest ways to avoid permission mistakes before you touch chown, chmod, deploy files, or troubleshoot "Permission denied".
- Check who you are:
id - Get just the username:
id -un - Get groups as names:
id -nG - Check the web-server context:
sudo -u www-data id(or the user your stack runs as) - Use numeric IDs in scripts:
id -u,id -g,id -G
What id reports
The default output includes:
uid=: numeric user ID and usernamegid=: numeric primary group ID and group namegroups=: supplementary groups (numeric and name)
Example:
uid=1001(devuser) gid=1001(devuser) groups=1001(devuser),27(sudo),33(www-data)
How to read that on a WordPress server:
- If your deploy user is in
www-data, you can often collaborate safely using group permissions. - If the web server runs as
www-data(common on Debian/Ubuntu), group ownership matters. - If the web server runs as
nobody/nogroup(often seen with OpenLiteSpeed defaults), you need to align ownership and group strategy accordingly.
Common commands
# Current process identity
id
# Identity for another user
id siteuser
# Numeric IDs (useful for scripts and comparisons)
id -u
id -g
id -G
# Names instead of numbers
id -un
id -gn
id -nG
Numbers vs names
Use names when you are reasoning as a human. Use numbers when you are writing automation (numeric IDs are the actual kernel-level identity).
Examples:
id -u siteuser
id -gn siteuser
id -nG siteuser
WordPress permission planning with id
Before you change ownership, decide your operational model. Two common models:
- "Site user owns code" + "Web user writes to specific dirs"
- Code owned by a deploy user (example:
siteuser) - Web server user (example:
www-data) is granted write access only where needed - Typical writable dirs:
wp-content/uploads/, cache dirs, and sometimeswp-content/litespeed/
- "Group collaboration" model
- Directories are owned by
siteuser:www-data(or another shared group) - Group write is enabled only where needed
id -nG siteusertells you if the user is in the shared group
Be careful with recursive ownership changes.
chown -R on the wrong path can break your site or make a restore harder.
Always confirm identity (id) and the target path (pwd, ls, realpath) first.
Check the web server and PHP identity
id tells you your current shell identity.
But file writes are often performed by the web server or PHP worker.
Confirm service user/group (systemd)
If your stack uses systemd services, check the configured User/Group:
systemctl show -p User -p Group nginx || true
systemctl show -p User -p Group apache2 || true
systemctl show -p User -p Group lsws || true
systemctl show -p User -p Group php8.2-fpm || true
Confirm a running process identity
ps -eo user,group,comm | egrep 'nginx|apache2|lshttpd|lsws|php-fpm|lsphp' | head
Simulate "as the web user"
This is useful when debugging why a plugin cannot write:
sudo -u www-data id || true
sudo -u nobody id || true
Troubleshooting patterns
"Permission denied" when WordPress uploads
Checklist:
- Identify the web user (previous section).
- Identify the directory owner/group:
ls -ld wp-content/uploads
stat -c '%A %U:%G %n' wp-content/uploads
- Compare with
id -nG <web-user>orid -nG <site-user>.
Common fixes:
- Add the deploy user to the shared group (and log out/in to refresh groups).
- Use group ownership + group write only for writable directories.
"It works in SSH but fails in the browser"
That usually means your shell user is different from the web/PHP user. Use:
id
sudo -u www-data id || true
Reference: flags
Flags you will use most
id # current user identity
id USER # identity for a user
id -u [USER] # UID only
id -g [USER] # primary GID only
id -G [USER] # all group IDs
id -un [USER] # username only
id -gn [USER] # primary group name only
id -nG [USER] # all group names
Lab: diagnose a WordPress write issue
Use this mini-lab on a staging site.
- Identify your deploy user identity:
id
id -nG
- Identify the web user identity:
sudo -u www-data id || true
- Inspect the uploads directory:
ls -ld wp-content/uploads
stat -c '%A %U:%G %n' wp-content/uploads
- Decide the fix (group model vs strict writable dirs) and document the outcome. 1001
### Primary GID-only (number vs name)
```bash
id -g # -> 1001
id -gn # -> devuser
Supplementary groups (numbers vs names)
id -G # -> 1001 27 33
id -nG # -> devuser sudo www-data
Check as another user (without logging in)
sudo -u siteuser id
Expected (example):
uid=1002(siteuser) gid=1002(siteuser) groups=1002(siteuser),33(www-data)
WordPress-Focused Use Cases
- Validate web server collaboration
-
Ensure the site owner (e.g.,
siteuser) is in thewww-datagroup so PHP/web server can write towp-content/uploads, cache, and temporary directories **without 777.id siteuser # look for www-data in groups
- Before fixing ownership recursively
-
Confirm who should own the tree:
id siteuser# Then apply:# sudo chown -R siteuser:www-data /home/siteuser/devwp/public_html
Use id to avoid typos like siteusr prevents broken ownership.
- Cross-check odd plugin write errors
-
If a plugin cant write, verify your PHP-FPM/OLS/PHP user and ensure group alignment:
id www-dataps -o user,group,comm -C lshttpd -C php-fpm -C php-fpm8.3
- Safer deploys
-
Scripts can branch based on identity:
if [ "$(id -u)" -ne 0 ]; then echo "Run with sudo"; exit 1; fi
- Multi-tenant sanity
- Verify each tenant user isnt accidentally in another tenants group.
Best Practices
- Use groups, not 777: Put
siteuserintowww-data; set dirs775, files664, then verify withid. - Script with numeric IDs:
id -u,id -g,id -Gare stable for logic branching. - Check before change: Always run
id <targetuser>beforechown -R. - Align service users: Know which user runs PHP/OLS; ensure proper group mapping.
Common Mistakes & How to Avoid
| Mistake | Symptom | Fix with id |
|---|---|---|
| Assuming current user owns the site | Permission denied, WP can’t write | id and id siteuser to verify, then chown properly |
| Relying on 777 | Works but unsafe | Use id to confirm group (www-data), set 775/664 |
| Wrong user in scripts | Random failures | Guard scripts: if [ "$(id -u)" -ne 0 ]; then … |
| Forgetting supplementary groups | Group write fails | id -nG siteuser to confirm www-data membership |
Troubleshooting Matrix
| Problem | Quick Checks | Next Steps |
|---|---|---|
Plugin can’t write to uploads | id -nG siteuser has www-data? | sudo usermod -aG www-data siteuser; reset perms |
| Mixed ownership after migration | id siteuser, ls -l on tree | sudo chown -R siteuser:www-data <root> |
| PHP runs as different user | ps -o user,group,comm -C php-fpm -C lshttpd | Align group membership; set SGID on dirs if needed |
| Sudo tasks failing | id -nG lacks sudo | Add to sudo group (with care); re-login |
Quick Lab (5 minutes)
-
See yourself
id -
Check web user
id www-data -
Confirm site user
id siteuserid -nG siteuser -
Dry-run ownership plan
-
If
www-datais missing fromsiteusergroups, add it (then new login required):sudo usermod -aG www-data siteuser
Re-check:
id -nG siteuser
Cheat Sheet
- Full:
id [user] - UID only:
id -u [user] - GID only:
id -g [user] - All GIDs:
id -G [user] - Names (swap numbersnames): add
nid -nG [user] - As another user:
sudo -u <user> id
Mini-Quiz
- Which command shows all **group names for
siteuser?
**Answer: id -nG siteuser
- You need only the numeric UID of the current user for a script.
**Answer: id -u
- A plugin cant write to
wp-content/cache. What do you verify first withid?
**Answer: That the site user is in the www-data group (or equivalent).
- Your script must abort unless root runs it. Write the guard.
**Answer: if [ "$(id -u)" -ne 0 ]; then echo "Run with sudo"; exit 1; fi
Wrap-up
id is tiny but critical: it tells you the truth about identities and groups. Use it before any permission/ownership operation so your WordPress VPS stays both **functional and securewithout falling back to reckless 777.