A capital X in posix / chmod

chmodpermissionsposix

I know what's ugoa (owner, group, others, all) or rwx (read/right/execute) or 4,2,1 or -, f, d, l, and I tried to read in man chmod to understand what's a capital X in chmod but there wasn't an entry for it. I then read in this article in posix/chmod but was stuck in this passage:

Set the executable bit only if the target a) is a directory b) has
already at least one executable bit set for any one of user, group,
others.

I also read in this article that gives this code example:

chmod -R u=rwX,g=rX,o=rX testdir/

I understand there is a recursive permission on the testdir/, in regards to the owner (u), group (g), and others (o) but I admit I still miss the intention of the capital X.

Maybe a didactic phrasing here could shed some light on this (the main reason I publish this here is because I didn't find an SE session on this).

Update

Sorry all, I missed that in the man. I didn't imagine the X would appear before the list of arguments and I thought the search returns x instead X, my bad.

Best Answer

The manpage says:

execute/search only if the file is a directory or already has execute permission for some user (X)

POSIX says:

The perm symbol X shall represent the execute/search portion of the file mode bits if the file is a directory or if the current (unmodified) file mode bits have at least one of the execute bits (S_IXUSR, S_IXGRP, or S_IXOTH) set. It shall be ignored if the file is not a directory and none of the execute bits are set in the current file mode bits.

This is a conditional permission flag: chmod looks at whatever it is currently processing, and if it’s a directory, or if it has any execute bit set in its current permissions (owner, group or other), it acts as if the requested permission was x, otherwise it ignores it. The condition is verified at the time chmod applies the specific X instruction, so you can clear execute bits in the same run with a-x,a=rwX to only set the executable bit on directories.

You can see whether a file has an execute bit set by looking at the “access” part of stat’s output, or the first column of ls -l. Execute bits are represented by x. -rwxr-xr-x is common for executables and indicates that the executable bit is set for the owner, group and other users; -rw-r--r-- is common for other files and indicates that the executable bit is not set (but the read bit is set for everyone, and the write bit for the owner). See Understanding UNIX permissions and their attributes which has much more detail.

Thus in your example, u=rwX sets the owner permissions to read and write in all cases, and for directories and executable files, execute; likewise for group (g=rX) and other (o=rX), read, and execute for directories and executable files.

The intent of this operator is to allow the user to give chmod a variety of files and directories, and get the correct execute permissions (assuming none of the files had an invalid execute bit set). It avoids having to distinguish between files and directories (as in the traditional find . -type f -exec chmod 644 {} + and find . -type d -exec chmod 755 {} + commands), and attempts to deal with executables in a sensible way.

(Note that macOS chmod apparently only supports X for + operations.)

Related Question