Point chown at a file and say who owns it — the fix for permissions that came out wrong
That file says root owns it, but the process that needs it runs as you — and here comes the one command that settles it.
chown (change owner) rewrites the user and/or group fields on a file or directory's inode. Syntax is always owner, then an optional :group: `chown alice file`, `chown alice:dev file`, or `chown :dev file` to touch only the group. It is a chmod cousin with different powers: chmod deals in r/w/x bits, chown decides WHO those bits belong to. You need it the moment a service runs as its own user (nginx, postgres, www-data) but a file got dropped there by root.
A normal user can never hand a file to someone else — that would let you trivially steal every other account's files. So chown is root-only: either you run it as root or you sudo. Running it without privileges gives you `chown: changing ownership of 'file': Operation not permitted`, which I watched happen live on this box. That's not a bug, it's the kernel guarding the ownership metadata.
-R walks a whole directory tree so `chown -R www-data:www-data /var/www` fixes every file and subdirectory in one pass — the standard repair after an extraction or a botched deploy. --reference copies the exact owner:group from a known-good file instead of you typing them. And chown accepts plain names or numeric uid:gid, so scripts can target specific IDs like UID 1000.
$ chown alice ./config.ini $ ls -l --no-group config.ini
$ chown alice ./config.ini $ ls -l --no-group config.ini -rw-r--r-- 1 alice 4096 Sep 22 09:12 config.ini
Root hands a single file over to alice. Only the owner changes; the group field is untouched. This is the one-two punch after a deploy drops a config with the wrong owner.
$ sudo chown www-data:www-data /var/www/app $ sudo chown -R www-data:www-data /var/www/app/storage
$ sudo chown www-data:www-data /var/www/app $ sudo chown -R www-data:www-data /var/www/app/storage $ ls -l /var/www/app/storage -rw-r--r-- 1 www-data www-data 12804 Sep 22 09:15 cache.bin -rw-rw---- 1 www-data www-data 5120 Sep 22 09:15 sessions.db -rw-r--r-- 1 www-data www-data 880 Sep 22 09:15 log.html
The classic web-tool chain: first fix the top, then -R descends and rewrites every file and subdir so the app's own user can read, write, and clean up its state. Run this after any unzip -q as root.
$ sudo chown 1000:1000 data/ $ stats
$ sudo chown 1000:1000 data/ $ stat -c '%A %U:%G %n' data/file.bin data/file.bin -rw-r--r-- kmail:kmail data/file.bin
Numeric uid:gid form — no name lookup needed, so it's faster and works even if an account is missing from /etc/passwd. UID 1000 is usually the first real user on a fresh box.
$ sudo chown --reference=template.config newdir/config.ini $ stat -c '%U:%G %n' newdir/config.ini template.config
$ sudo chown --reference=template.config newdir/config.ini $ stat -c '%U:%G %n' newdir/config.ini template.config kmail:kmail newdir/config.ini kmail:kmail template.config
--reference copies the owner:group of a known-good file instead of you typing them — handy when you forget which combo the rest of the tree uses.
$ chown mail ./own.txt $ ls -l --no-group own.txt
$ chown mail ./own.txt chown: changing ownership of 'own.txt': Operation not permitted $ ls -l --no-group own.txt -rw-rw-r-- 1 kmail kmail 5 Sep 22 09:03 own.txt
Verified live on this box as an unprivileged user: handing your file to the 'mail' group is denied — Operation not permitted, and the file is untouched. chown is root-only. Reach for sudo.
| Flag | Meaning |
|---|---|
chown OWNER:GROUP FILE | The full form. Set both owner and group at once. Omit the colon+group to change only the owner. |
-R / --recursive | Walk a directory tree and apply the change to every file and subdir. The -R you'll actually use. |
--reference=FILE | Copy the owner:group from another file instead of spelling them out. Great when you forget the exact combo. |
:GROUP (leading colon) | Change only the group: `chown :dev file`. Owner stays put — a one-word way to widen team access. |
-h / --no-dereference | Change a symlink's ownership instead of following it to the target file it points at. |
-v / --verbose | Print a line for every file changed. Combine with -R to watch a big tree get fixed in real time. |
chown has existed since the very first Unix releases at Bell Labs in the early '70s, alongside chmod, chgrp, and the notion that every file carries a user ID and group ID. The idea — files belonging to people, not just sitting in a namespace — is one of the oldest and most copied parts of Unix, and chown is the command that edits ownership where chmod edits permission bits.
Early Unix realized that if any user could give their files to another user, there'd be no way to keep accounts apart. So chown became root-only, and that restriction survived decades precisely because removing it would let a normal user fabricate ownership and, in some cases, gain other users' privileges. The 'Operation not permitted' error you hit is that decades-old guard still standing.