A nice way to find out whether chown
actually changes ownership
of files even if they stay the same (e.g. from pduck
to pduck
)
is to run the command under strace
. This way we can see the APIs
that actually get called.
I created a test file which is owned by me and my group.
Then I did chown pduck:pduck test.txt
but with strace
prepended:
$ touch test.txt
$ ls -l
total 0
-rw-r--r-- 1 pduck pduck 0 Jun 16 12:10 test.txt
$ strace chown pduck:pduck test.txt
execve("/bin/chown", ["chown", "pduck:pduck", "test.txt"], 0x7ffd0309c990 /* 74 vars */) = 0
brk(NULL) = 0x5589645df000
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
...
newfstatat(AT_FDCWD, "test.txt", {st_mode=S_IFREG|0644, st_size=0, ...}, AT_SYMLINK_NOFOLLOW) = 0
fchownat(AT_FDCWD, "test.txt", 1000, 1000, 0) = 0
close(1) = 0
close(2) = 0
exit_group(0) = ?
+++ exited with 0 +++
As we can see, the ownership is indeed unconditionally changed from
pduck:pduck to 1000:1000 (which are the numerical IDs of pduck:pduck).
You have multiple options:
chown --from=pduck:pduck pgoose:pgoose text.txt
Will only change the ownership to pgoose:pgoose
if it currently is pduck:pduck
.
Files with other ownerships remain untouched. Add -R
to make the changes
recursively.
find . -type f -user pduck -group pduck -exec chown pgoose:pgoose {} +
This will (recursively) find all files owned by pduck:pduck and only
for them run chown pgoose:pgoose …
.
find . -type f -not -\( -user pduck -or -group pduck -\) -exec chown pduck:pduck {} +
Changes ownership of files that do not belong to user pduck
or group pduck
.
As long as you don't have hundreds of thousands of files I don't think there is
much difference in the performance.
When I do chown -R ...
then usually because a whole directory has "wrong" ownership
(for example on thumbdrives). But I usually never do chmod -R
because files
and directories need different permissions and the x
has a different meaning for them.
We have many questions here on how to fix that terrible chmod -R 777 …
thing.
Instead, I do it in two separate commands (find -type d …
and find -type f …
).
chmod -R
, the execute bit is not my worry. As seen on this site,chown -R user:user /
seems to be a bigger problem ;) – vidarlo Jun 16 '19 at 11:07