[Rd] unlink() on "~" removes the home directory

Gábor Csárdi c@@rd|@g@bor @end|ng |rom gm@||@com
Wed Feb 26 23:47:49 CET 2020


Well, unlink() does what it is supposed to do, so you could argue that
there is nothing wrong with it. Also, nobody would call unlink() on
"~", right?

The situation is not so simple, however. E.g. if you happen to have a
directory called "~", and you iterate over all files and directories
to selectively remove some of them, then your code might end up
calling unlink on the local "~" directory, and then your home is gone.

But you would not create a directory named "~", that is just asking
for trouble. Well, surely, _intentionally_ you would not do that.
Unintentionally, you might. E.g. something like this is enough:

# Create a subpath within a base directory
badfun <- function(base = ".", path) {
  dir.create(file.path(base, path), recursive = TRUE, showWarnings = FALSE)
badfun(path = "~/foo")

(If you did run this, be very careful how you remove the directory called "~"!)

A real example is `R CMD build` which deletes the home directory of
the current user if the root of the package contains a non-empty "~"
directory. Luckily this is now fixed in R-devel, so R 4.0.0 will do
better. (R 3.6.3 will not.) See

I have seen several bug reports about various packages (that call R
CMD build) removing the home directory, so this indeed happens in
practice to a number of people. The commit above will fix `R CMD
build`, but it would be great to "fix" this in general.

It seems pretty hard to prevent users from creating of a "~"
directory. But preventing unlink() from deleting "~" does not actually
seem too hard. If unlink() could just refuse removing "~" (when expand
= TRUE), that would be great. It seems to me that the current behavior
is very-very rarely intended, and its consequences are potentially

If unlink("~", recursive = TRUE) errors, you can still remove a local
"~" file/dir with unlink("./~", ...). And you can still remove your
home directory if you really want to do that, with
unlink(path.expand("~"), ...). So no functionality is lost.

Also, if anyone is aware of packages/functions that tend to create "~"
directories or files, please let me know.

I would be happy to submit a patch for the new unlink("~") behavior.


More information about the R-devel mailing list