Does `ln -sf` overwrite existing files which are only symbolic links
Solution 1
In UNIX, directories are special (I feel myself channeling The Church Lady from SNL). Directories contain other files, so deleting them requires a different operation. Even when a directory is empty it still has two files in it (.
and ..
) so deleting a directory can't be done until it's really empty and the link counts on the relevant files have been updated.
In the early days of UNIX (my first experience is with 6th edition from Bell Labs) there were two different commands (rm
and rmdir
) for regular files and directories, which reflected the underlying fact that they were two different system calls. rm
was simple, it just removed the entry whose name you gave it from the directory, and decremented the ref count on the file it pointed to (of course, the file is not actually deleted unless the ref count goes to 0). rmdir
required much more (not actually in the app, but in the system call), it had to go into the directory and find the .
and ..
entries, go to those inodes and decrement the ref count, and then remove the entry in the parent and decrement that ref count (the same one it just decremented for .
in the directory itself, which should then be 0). All of that straddled several different disk sectors, and so had to be carefully tuned to make the possibility of an abort (i.e. system crash) at any point be recoverable by fsck.
Of course, in more modern UNIX systems the constraints of the hardware (i.e. 64Kbyte max program size, that is a "K") have been eased and you can now do rm -r
and a lot of that underlying special nature of directories is less apparent, but it's still there. I remember needing to delete a large tree on the 6th edition machine which involved going into each directory, deleting all the files, going back to the parent and doing rmdir
and essentially doing all the recursion down all the directory trees manually. We did think about a script to help with this, but it came up so seldom in those days and it was sufficiently dangerous that we decided that requiring someone to go to all that effort would help prevent catastrophic mistakes.
The first time you get a question that says "I typed 'sudo rm -rf /
' instead of ./
how do I recover?" you may understand why we were being cautious.
Solution 2
It can remove files, but directories are not "files".
➜ lab touch file
➜ lab mkdir dir
➜ lab ln -sfT /home file
➜ lab ln -sfT /home dir
ln: dir: cannot overwrite directory
This is seen in the source:
if (remove_existing_files || interactive || backup_type != no_backups)
{
dest_lstat_ok = (lstat (dest, &dest_stats) == 0);
if (!dest_lstat_ok && errno != ENOENT)
{
error (0, errno, _("failed to access %s"), quoteaf (dest));
return false;
}
}
[...]
if (dest_lstat_ok)
{
if (S_ISDIR (dest_stats.st_mode))
{
error (0, 0, _("%s: cannot overwrite directory"), quotef (dest));
return false;
}
if (interactive)
{
fprintf (stderr, _("%s: replace %s? "), program_name, quoteaf (dest));
if (!yesno ())
return true;
remove_existing_files = true;
}
dest_lstat_ok
boolean which starts as false becomes true, the first if statement is called since remove_existing_files
is true due the --force
flag, which in turn allows the second if statement to be checked. It refuses to remove directories because it's expecting a file.
If you don't set the -T
which makes ln to not treat the directory as not a directory, ln would just created a symlink under the directory with the basename of the source.
Related videos on Youtube
![Tim](https://i.stack.imgur.com/3PCjR.png?s=256&g=1)
Tim
Elitists are oppressive, anti-intellectual, ultra-conservative, and cancerous to the society, environment, and humanity. Please help make Stack Exchange a better place. Expose elite supremacy, elitist brutality, and moderation injustice to https://stackoverflow.com/contact (complicit community managers), in comments, to meta, outside Stack Exchange, and by legal actions. Push back and don't let them normalize their behaviors. Changes always happen from the bottom up. Thank you very much! Just a curious self learner. Almost always upvote replies. Thanks for enlightenment! Meanwhile, Corruption and abuses have been rampantly coming from elitists. Supportive comments have been removed and attacks are kept to control the direction of discourse. Outright vicious comments have been removed only to conceal atrocities. Systematic discrimination has been made into policies. Countless users have been harassed, persecuted, and suffocated. Q&A sites are for everyone to learn and grow, not for elitists to indulge abusive oppression, and cover up for each other. https://softwareengineering.stackexchange.com/posts/419086/revisions https://math.meta.stackexchange.com/q/32539/ (https://i.stack.imgur.com/4knYh.png) and https://math.meta.stackexchange.com/q/32548/ (https://i.stack.imgur.com/9gaZ2.png) https://meta.stackexchange.com/posts/353417/timeline (The moderators defended continuous harassment comments showing no reading and understanding of my post) https://cs.stackexchange.com/posts/125651/timeline (a PLT academic had trouble with the books I am reading and disparaged my self learning posts, and a moderator with long abusive history added more insults.) https://stackoverflow.com/posts/61679659/revisions (homework libels) Much more that have happened.
Updated on September 18, 2022Comments
-
Tim almost 2 years
From the coreutils
ln
manual:Normally ln does not remove existing files. Use the --force (-f) option to remove them
unconditionally, the --interactive (-i) option to remove them conditionally,
and the --backup (-b) option to rename them.$ mkdir output
I can understand this failing:
$ ln -sT /etc/passwd output ln: failed to create symbolic link ‘output’: File exists
But why does adding
-f
also fail:$ ln -sfT /etc/passwd output ln: ‘output’: cannot overwrite directory
Does
-f
overwrite existing files which are only symbolic links, but not files of other types (directories, regular files, ...)?Can
-T
be used when the last argument, (i.e. the target file argument), is an existing directory, with the intention to overwrite the directory into a link?-
Admin almost 8 yearsDo you think it would be a wise idea to have a simple flag effectively turn
ln
intorm -rf
? -
Admin almost 8 yearswhat do you mean by 'have a simple flag turn ln into rm -rf '?
-
Admin almost 8 yearsln
-fT
would have to remove the target directory forcibly and recursively, to the effect of runningrm -rf
on it. That's a very dangerous operation, better left torm
, away from commands likeln
which tend to create more than they destroy. -
Admin almost 8 yearsIt is even more interesting if you leave
-T
out but ask for a relative link. e.g.mkdir output; ln -sf this/that output
. It results in a (broken) linkthat -> this/that
. -
Admin almost 8 yearsYou should probably fix the title to more accurately describe the question. In the body you don't ask about either overwriting files or existing symbolic links, it asks about directories which aren't in the title at all.
-
-
Tim almost 8 yearsthanks. so it doesn't work when the existing file is a directory. does it work when the existing file is a file which is not a directory but other file types?
-
Ludwig Schulze almost 8 years@Tim the source doesn't seems to have other checks.