I have the habit to chmod with the relative notation (e.g. g+w or a+r or go‑w or similar) instead of the absolute one (e.g. 0640 or u=rw,g=r,o=). Recently I had to chmod a lot of files. As usual I was using the relative notation. With a lot of files, this took a lot of time. Time was not really an issue, so I did not stop it to restart with a better performing command (e.g. find /path ‑type f ‑print0 | xargs ‑0 chmod 0644; find /path ‑type d ‑print0 | xargs ‑0 chmod 0755), but I thought a little tips&tricks posting may be in order, as not everyone knows the difference.
The relative notation
When you specify g+w, it means to remove the write access for the group, but keep everything else like it is. Naturally this means that chmod first has to lookup the current access rights. So for each async write request, there has to be a read-request first.
The absolute notation
The absolute notation is what most people are used to (at least the numeric one). It does not need to read the access rights before changing them, so there is less I/O to be done to get what you want. The drawback is that it is not so nice for recursive changes. You do not want to have the x‑bit for data files, but you need it for directories. If you only have a tree with data files where you want to have an uniform access, the example above via find is probably faster (for sure if the directory meta-data is still in RAM).
If you have a mix of binaries and data, it is a little bit more tricky to come up with a way which is faster. If the data has a name-pattern, you could use it in the find.
And if you have a non-uniform access for the group bits and want to make sure the owner has write access to everything, it may be faster to use the relative notation than to find a replacement command-sequence with the absolute notation.
Thanks for interesting reading.
You have small typo:
“When you specify g+w, it means to remove the write access for the group…”
It should be “g‑w”
you made a typo: g+w *adds* write access for the group 🙂
The examples are just examples. I did not intend to give the same examples for absolute and relative notation (which is impossible without showing a file/directory with specific access rights). g+w adds group write access no matter what other settings are there, whereas the absolute examples do not keep the remaining access rights. Please do not compare them.
Current chmod command implementations have already read the stat structure before setting the new permissions (checked on FreeBSD and Solaris source), so there is really no benefit for absolute mode over symbolic mode.
Even absolute mode is not 100% absolute. For non-regular files the interpretation is implementation dependent. Quoting Solaris man page for chmod(1):
For directories, the setgid bit cannot be set (or cleared)
in absolute mode; it must be set (or cleared) in symbolic
mode using g+s (or g‑s).
Also the inode should already be in the inode cache. Even find needs the stat structure (-type f).
Now the question is: why does chmod in absolute mode need to read the stat structure (on FreeBSD)?