To change the owner of a directory and everything inside it, the quick answer:
sudo chown -R user:group /path/to/directory
And to change permissions recursively:
sudo chmod -R 755 /path/to/directory
The -R flag means recursive: apply to the directory, every file in it, and every subdirectory all the way down. Read on before running the chmod version though, because giving files and directories the same mode is usually not what you want.
chown recursive, explained
chown sets the user and group that own a file. The common forms:
sudo chown -R alice /var/www/app # change owner only
sudo chown -R alice:developers /var/www/app # owner and group
sudo chown -R :developers /var/www/app # group only
You can use numeric IDs instead of names (chown -R 1000:1000 ...), which is useful inside containers or when the name does not exist on the host. Check the result with:
ls -l /var/www/app
stat /var/www/app/index.html
A classic example on a web server: after uploading files as root, hand them to the web server user so it can read them:
sudo chown -R www-data:www-data /var/www/html
The chmod recursive trap: files vs directories
Directories need the execute bit to be entered; regular files usually should not have it. A blanket chmod -R 755 makes every file executable, and chmod -R 644 makes directories unenterable. The right pattern is different modes for each type:
find /var/www/app -type d -exec chmod 755 {} +
find /var/www/app -type f -exec chmod 644 {} +
Or in one pass, use the capital X, which applies execute only to directories and to files that are already executable:
sudo chmod -R u=rwX,go=rX /var/www/app
That one line is the safest general purpose recursive permission fix: owner gets read/write, everyone gets read, and only directories become traversable.
What the numbers mean
- 7 = read + write + execute (rwx)
- 6 = read + write (rw-)
- 5 = read + execute (r-x)
- 4 = read only (r--)
The three digits apply to owner, group, and others in that order. So 755 is rwx for the owner and r-x for everyone else, and 644 is rw- for the owner and r-- for everyone else. Those two are the standard pair for web content.
Things not to do
- Do not run chmod -R 777. It makes every file writable and executable by every user on the system. It "fixes" permission errors by removing all protection, and on a shared or internet facing machine it is an invitation for trouble. Fix ownership with chown instead; 777 is almost never the correct answer.
- Be careful with the target path. A stray space (
chmod -R 755 / var/www) turns the command into one that rewrites the entire filesystem. Double check the line before pressing enter, especially as root. - Mind symlinks. By default
chown -Rchanges the link itself, not what it points to, andchmodfollows the link. If your tree contains symlinks pointing outside it, review them first withfind /path -type l -ls.
Common errors
- Operation not permitted: only root may change a file owner. Use
sudo. If you are root and still see this, the file may be on a read only mount or have the immutable attribute set (lsattr file, remove withchattr -i file). - invalid user: alice:developers: the user or group does not exist on this machine. Create it or use numeric IDs.
- chmod changing permissions of ... Read-only file system: the filesystem is mounted read only; remount it read write before changing anything.
Copying ownership and permissions from a reference
When one file already has the right settings, you can clone them instead of spelling them out:
chmod --reference=good-file.txt broken-file.txt
chown --reference=good-file.txt broken-file.txt
Both flags also combine with recursion. And when moving content between locations, preserve ownership and modes during the copy instead of fixing them afterwards:
cp -a source/ destination/ # archive mode keeps owner, mode, timestamps
rsync -a source/ destination/ # same idea over the network
Note that preserving ownership requires running the copy as root; as a normal user, cp -a silently keeps your own ownership.
Related commands
chgrp -R group /path: change group only, equivalent tochown -R :groupumask: controls the default permissions newly created files getid username: show a user's numeric ID and groups before you chown to them
These commands behave identically on every mainstream distribution, so the same muscle memory works on your laptop, a container, or a Linux VPS in production.