chown
Change which account and group own a file
chown sets which account owns a file and, with a colon, which group. chmod
decides what the owner and the group may do; chown decides who they are.
It needs root, and not only for other people's files. Linux has no way to give away a file you own outright: the rule stops a disk quota being dodged by handing a large file to a stranger, and it means anything a script passes to another account has to be passed back by root.
Changing the group is looser. You may change a file's group if you own the file and belong to the
group you are naming, which is why adding an account to a group with usermod -aG is the usual
first step in setting up a shared directory.
Sample files used on this page
Every example below was run against these files. Recreate them to follow along.
site the tree the cp, mv and rm pages use, owned by user before every example
site:
total 16
drwxr-xr-x 2 user user 4096 Jun 15 10:00 assets
drwxr-xr-x 2 user user 4096 Jun 15 10:00 backups
-rw-r--r-- 1 user user 36 Jun 1 09:00 index.html
lrwxrwxrwx 1 user user 9 Jun 18 09:00 latest.css -> style.css
-rw-r--r-- 1 user user 33 Jun 20 09:00 style.css
site/assets:
total 4
-rw-r--r-- 1 user user 35 Jun 10 09:00 logo.svg
site/backups:
total 0
notes.txt one line, owned by user, beside site/ rather than inside it
Rebuild before deploying.
the accounts a second account and a second group for the files to be handed to, both created by the setup script
uid=1500(deploy) gid=1500(webdev) groups=1500(webdev)
uid=1000(user) gid=1000(user) groups=1000(user)
Setting the owner and the group
chown owner file, chown owner:group file, chown :group file. Every one of these needs root, which is the first thing to know about the command.
Change who owns a file
chown deploy notes.txt && ls -l notes.txt
The owner column changes and the group is left alone, so the file is now deploy's but still in user's group.
Show output
-rw-r--r-- 1 deploy user 26 Jun 10 09:00 notes.txt
Change both at once
chown deploy:webdev notes.txt && ls -l notes.txt
A colon separates the two. A dot works as well and is older; the colon is preferred because a username may legally contain a dot.
Show output
-rw-r--r-- 1 deploy webdev 26 Jun 10 09:00 notes.txt
Change only the group
chown :webdev notes.txt && ls -l notes.txt
Leave the name off the left of the colon and the owner is untouched.
Show output
-rw-r--r-- 1 user webdev 26 Jun 10 09:00 notes.txt
Or use chgrp, which does nothing else
chgrp webdev notes.txt && ls -l notes.txt
chgrp is chown :group with its own name, and it takes the same -R, -v and --reference flags. Use whichever reads better in the script you are writing.
Show output
-rw-r--r-- 1 user webdev 26 Jun 10 09:00 notes.txt
Set the group to the new owner's own
chown deploy: notes.txt && ls -l notes.txt
A trailing colon with nothing after it means "and that account's login group". deploy's is webdev, so both columns change from one argument.
Show output
-rw-r--r-- 1 deploy webdev 26 Jun 10 09:00 notes.txt
Say what changed
chown -v deploy notes.txt
-v (--verbose) prints a line per file whether or not anything moved.
Show output
changed ownership of 'notes.txt' from user to deploy
Say only what actually changed
chown -c deploy notes.txt; chown -c deploy notes.txt; echo "the second run printed nothing"
-c (--changes) is -v without the noise: it reports the files it altered and stays quiet about the ones already correct. On a chown -R over a tree that is mostly right, this is the difference between one line and ten thousand.
Show output
changed ownership of 'notes.txt' from user to deploy
the second run printed nothing
Reject a name that does not exist
chown nosuchuser notes.txt
The check happens before anything is touched, and the exit status is 1. A numeric id is never rejected this way, because any number is a valid owner.
Show output
chown: invalid user: 'nosuchuser'
Whole trees
Recurse into a directory
chown -R deploy:webdev site && stat -c '%U:%G %n' site site/assets site/assets/logo.svg
-R (--recursive) covers the directory, everything in it and everything below. stat -c is used here in place of ls because it prints no timestamps.
Show output
deploy:webdev site
deploy:webdev site/assets
deploy:webdev site/assets/logo.svg
A glob is not the same as -R
touch site/.htaccess && chown user:user site/.htaccess && chown -R deploy site/* && stat -c '%U %n' site/.htaccess site/index.html
site/* is expanded by the shell, and a plain glob skips anything beginning with a dot. The .htaccess keeps its old owner while everything visible changes, which on a web root is the file you least wanted to miss.
Show output
user site/.htaccess
deploy site/index.html
Name the directory and the dotfiles come too
touch site/.htaccess && chown user:user site/.htaccess && chown -R deploy site && stat -c '%U %n' site/.htaccess site/index.html
chown -R deploy site walks the directory itself, so nothing depends on what the shell decided to expand.
Show output
deploy site/.htaccess
deploy site/index.html
Change only the files a particular account owns
chown --from=user:user deploy:webdev notes.txt site/index.html && ls -l notes.txt
--from makes the change conditional, and anything with a different owner is passed over. This is the flag for tidying up after one account on a tree that several of them write to.
Show output
-rw-r--r-- 1 deploy webdev 26 Jun 10 09:00 notes.txt
Copy the ownership from another file
chown deploy notes.txt && chown --reference=notes.txt site/index.html && ls -l site/index.html
--reference takes both columns from the file you name, so nothing has to be spelled out. Useful when restoring a file from a backup beside one that was left alone.
Show output
-rw-r--r-- 1 deploy user 36 Jun 1 09:00 site/index.html
What an ordinary account may and may not do
Linux has no way to give a file to someone else unless you are root. The rule exists so that disk quotas cannot be dodged by handing a large file to a stranger, and it catches people out because it applies to files you already own.
You cannot give away a file you own
sudo -u user chown deploy notes.txt
user owns notes.txt outright and still cannot pass it on. Only root may change an owner.
Show output
chown: changing ownership of 'notes.txt': Operation not permitted
You cannot change the group to one you are not in
sudo -u user chgrp webdev notes.txt
Changing the group is not root-only, but it is restricted: you must own the file and belong to the group you are naming.
Show output
chgrp: changing group of 'notes.txt': Operation not permitted
Join the group and the same command works
usermod -aG webdev user && sudo -u user chgrp webdev notes.txt && ls -l notes.txt
usermod -aG adds a supplementary group, and -a is what stops it replacing every other group the account is in. This is how a deployment account is given write access to a shared directory.
Show output
-rw-r--r-- 1 user webdev 26 Jun 10 09:00 notes.txt
Giving a file away only goes one way
chown deploy notes.txt && sudo -u user chown user notes.txt
Root moved the file to deploy and user cannot take it back, because taking it back is also a change of owner. Anything a script hands to another account has to be handed back by root.
Show output
chown: changing ownership of 'notes.txt': Operation not permitted
Symlinks, ids and one silent side effect
chown follows a symlink
chown deploy site/latest.css && ls -l site/latest.css site/style.css
The link is untouched and style.css, the file behind it, has changed hands. A symlink's own ownership means almost nothing, so this is usually what you wanted.
Show output
lrwxrwxrwx 1 user user 9 Jun 18 09:00 site/latest.css -> style.css
-rw-r--r-- 1 deploy user 33 Jun 20 09:00 site/style.css
Or change the link and leave the file alone
chown -h deploy site/latest.css && ls -l site/latest.css site/style.css
-h (--no-dereference) does the opposite of the default. Worth adding to any -R over a tree whose symlinks point somewhere you have no business rewriting.
Show output
lrwxrwxrwx 1 deploy user 9 Jun 18 09:00 site/latest.css -> style.css
-rw-r--r-- 1 user user 33 Jun 20 09:00 site/style.css
Ownership is a number underneath
chown 1500:1500 notes.txt && ls -ln notes.txt
Names are looked up in /etc/passwd and /etc/group; the filesystem stores integers. ls -ln shows the numbers, which is the view you want on a mounted disk from another machine, where the names will not line up.
Show output
-rw-r--r-- 1 1500 1500 26 Jun 10 09:00 notes.txt
chown clears setuid and setgid
chmod u+s notes.txt && ls -l notes.txt && chown deploy notes.txt && ls -l notes.txt
The S in the first listing is the setuid bit, and it is gone from the second. The kernel drops it on any change of owner, because a setuid file that changed hands would run as its new owner without anyone having said so. See chmod for what the bit does when it is set deliberately.
Show output
-rwSr--r-- 1 user user 26 Jun 10 09:00 notes.txt
-rw-r--r-- 1 deploy user 26 Jun 10 09:00 notes.txt
Hand a config file back to root
chown root:root site/index.html && ls -l site/index.html
The usual last step after editing something under /etc as a copy in your home directory. Ownership by root plus mode 644 is what most of /etc looks like.
Show output
-rw-r--r-- 1 root root 36 Jun 1 09:00 site/index.html