3 ms·
I once had to remove a LOT of files, so was looking how to do it efficiently -- find has a -delete option, so I straced it: $ touch a b c d e f g h /tmp/x
by rrauenza 9y ago
I once had to remove a LOT of files, so was looking how to do it efficiently -- find has a -delete option, so I straced it:
$ touch a b c d e f g h
/tmp/x $ strace find . -delete
execve("/usr/bin/find", ["find", ".", "-delete"], [/* 32 vars */]) = 0
[...]
openat(AT_FDCWD, ".", O_RDONLY|O_NOCTTY|O_NONBLOCK|O_DIRECTORY|O_NOFOLLOW) = 4
[...]
fcntl(4, F_DUPFD, 3) = 5
fcntl(5, F_GETFD) = 0
fcntl(5, F_SETFD, FD_CLOEXEC) = 0
getdents(4, /* 10 entries */, 32768) = 240
getdents(4, /* 0 entries */, 32768) = 0
close(4) = 0
fcntl(5, F_DUPFD_CLOEXEC, 0) = 4
unlinkat(5, "d", 0) = 0
unlinkat(5, "e", 0) = 0
unlinkat(5, "f", 0) = 0
unlinkat(5, "b", 0) = 0
unlinkat(5, "c", 0) = 0
unlinkat(5, "h", 0) = 0
unlinkat(5, "a", 0) = 0
unlinkat(5, "g", 0) = 0
[...]
exit_group(0) = ?
+++ exited with 0 +++
https://linux.die.net/man/2/unlinkat https://linux.die.net/man/2/unlinkat
int unlinkat(int dirfd, const char *pathname, int flags);
If the pathname given in pathname is relative, then it is interpreted relative to the directory referred to by the file descriptor dirfd (rather than relative to the current working directory of the calling process, as is done by unlink(2) and rmdir(2) for a relative pathname).
I would expect the reason for this is in case someone is moving directories around while the find is happening ... Each time find enters a directory it doesn't actually chdir(), so it opens that directory and uses it to anchor the removal.
rm -r does something similar.