== An important safety note about _chown_ and symlinks (also chmod and chgrp) Today I had a little Twitter exchange about a little (or not so little) thing that is not as well known as it should be: > [[@thatcks https://twitter.com/thatcks/status/1252231345457319936]]: > Ah yes, the eternal question: is it 'chown -Hr' or 'chown -hR' that I > want? > > (Answer: the second. Also, -h should be the default, at least with > -R.) > > [[@mrhoten https://twitter.com/mrhoten/status/1252243605684543489]]: > {{AB:TIL:Today I learned}} I have run some pretty dang risky chown > -R's and not even known it. For those who haven't encountered this particular combination of arguments for the [[_chown_ http://man7.org/linux/man-pages/man1/chown.1.html]] command, -R is a recursive chown through a directory hierarchy, while -h is, well, let me quote the manual (for GNU chown): > affect symbolic links instead of any referenced file (useful > only on systems that can change the ownership of a symlink) (Similar wording is in [[the FreeBSD chown manpage https://www.freebsd.org/cgi/man.cgi?query=chown&sektion=8]].) Let me translate this. If you run plain '_chown -R user.group dirtree_', and the directory tree contains symlinks that point outside itself, your recursive chown will change the ownership of the files that those symlinks point to. Is there a symlink to _/etc/shadow_? Well, you just changed its ownership. ~~A recursive _chown_ without _-h_ can do random damage to owners and groups anywhere on your system~~. Recursive chowns aren't the only time this comes up. Consider '((chown user.group *))' in a directory, to fix ownership for the user. If there are any symlinks, congratulations, you once again changed the ownership of random files on your system. ~~You should always use _-h_ with _chown_ unless you're sure you know what you're doing~~. You almost never want to change the ownership of the target of a symlink. (If you have a tangled chain of symlinks and you need to fix the permissions of the real underlying file behind them all, generally use [[_realpath_ http://man7.org/linux/man-pages/man1/realpath.1.html]] to find out what it is first.) Naturally the same thing applies to the _chgrp_ command. The GNU chmod command unfortunately lacks a _-h_ option, and will always change permissions on the target of symlinks given on the command line (which might happen in, for example, '((chmod g+r *))'). FreeBSD's [[_chmod_ https://www.freebsd.org/cgi/man.cgi?chmod]] does have a _-h_ option and you should always use it unless you're sure. === Sidebar: The potential bad state of OpenBSD and _chown_ The OpenBSD [[_chown_ https://man.openbsd.org/chown.8]] manpage contains the following hair-raising statement about the _-h_ option (emphasis mine): > Treat symbolic links like other files: modify links instead of > following them. ~~The _-h_ and _-R_ options are mutually > exclusive.~~ OpenBSD's _chown_ also has a -P argument, which is the default behavior in '_chown -R_'. This is described as: > If the _-R_ option is specified, no symbolic links are followed. It's not clear what OpenBSD's manpage means by 'followed' here. Are symbolic links that point to directories not descended into but symbolic links are chown'd in general, or are symbolic links entirely ignored, being neither chown'd nor descended into? If OpenBSD _chown_ really does follow the POSIX _chown_ specification, then [[the POSIX specification https://pubs.opengroup.org/onlinepubs/9699919799/utilities/chown.html]] is much clearer here and specifies the behavior we don't want: > If the _-R_ option is specified and a symbolic link is specified > on the command line or encountered during the traversal of a file > hierarchy, _chown_ shall change the owner ID (and group ID, if > specified) of the symbolic link. The _chown_ utility shall not follow > the symbolic link to any other part of the file hierarchy. ~~Update~~: I think I misread this and was wrong about the POSIX behavior, because it specifies that with _-P_, the symbolic link itself is chown'd. That would make it the behavior we want. If OpenBSD _chown_ really uses the POSIX behavior, then you can't safely use _chown_ on OpenBSD to change the ownership of a directory tree. You need to use a much more awkward _find_ command line to chown everything that isn't a symlink. (POSIX appears to implicitly forbid combining '_-h_' and '_-R_', but that's crazy and may be a mistake in POSIX.)