I have a blind spot where it comes to using chmod's symbolic modes

October 8, 2016

I've used Unix for long enough that I'm completely at home with the basic octal file modes, and in fact I generally think about file permissions in octal; mode 755 (or 0755) is a standard executable or script, and so on. These octal modes are what I reflexively use with chmod, find, and so on when I need to deal with permissions. I know vaguely in the back of my mind that the chmod command supports using symbolic modes, but I don't think about it much because I don't see any reason to use them. Why would I take the long way around to specifying modes in text when I can just use octal?

Well, that's a blind spot. As I was reminded recently, chmod's symbolic modes are more powerful than plain octal modes because they can be used not just to set permissions but to add and remove them. This may sound obscure, but it's extremely handy if you want to do a mass change to a bunch of files (and directories) that have a mix of 'proper' modes. For example, suppose that you have a directory of stuff that you want to remove general world access to. Unless you know there are no subdirectories (or executables, including shell scripts), you can't just do, say, 'chmod 640', because that might strip execute permission from things that need to keep it. This is where removing permissions symbolically wins:

chmod o-rwx *

Chmod's symbolic modes also know even more advanced tricks, like the special X mode. Do you want to give general world access to things in a directory, with execute set for executable files and directories but not for regular files? Here you go:

chmod o+rX *

Now, there's an interesting (to me) side note about the use of symbolic modes with chmod, which is that they make chmod's actions non-atomic. If you run two octal-mode chmods at the same time, you're normally guaranteed that the file will wind up with one of the two modes and nothing else; if you do 'chmod 644 fred' and 'chmod 711 fred' at the same time, fred winds up either mode 0644 or 0711. But the chmod(2) system call only sets modes it doesn't modify them, so when you use symbolic modes to add or delete modes, the chmod command has to read the current modes via some form of stat(2) system call, compute the new mode, and then write it back. These three steps are obviously non-atomic with other chmod commands running at the same time. If you do 'chmod g+r fred' and 'chmod o+r fred' at the same time, fred might wind up with group read, other read, or both other and group read; it depends on how the commands run.

(It's possible that some implementations of chmod aren't atomic even for octal modes. But they at least could be, since setting a specific octal mode value maps directly to a chmod(2) system call.)


Comments on this page:

Btw, in case this is part of your blind spot, note that “chmod o-rwx *” can also be spelled “chmod o= *”.

By liam at unc edu at 2016-10-14 09:47:13:

Another reason to remember symbolic mode, somtimes there are things you can only set in symbolic mode - eg from the Sun chmod(1) man page:

"Note that 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)."

Cheers, Liam

By cks at 2016-10-14 11:08:14:

Belatedly: I had indeed overlooked 'chmod o= *' as the easy way to strip all permissions for others (and 'chmod go= *' to make it 'only me'). I've only just started paying attention to the symbolic modes, so it's going to take me a while to fully wake up to them.

By Ben C at 2018-09-08 03:50:39:

The Linux chmod supports octal with the + and - operators. So your first command can equivalently be written “chmod -007 *”.

Written on 08 October 2016.
« Why OmniOS boot environments don't solve our upgrade issues
What I think I want out of CPU performance in a new PC »

Page tools: View Source, View Normal, Add Comment.
Search:
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Sat Oct 8 00:09:09 2016
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.