Let's say I have two directories in Linux, /A
and /B
, a program uses /A
, and I want now point /A
to /B
so that the program now sees /B
when reading /A
.
This is one way I could do that:
rm -rf /A
mv /B /A
Alternatively, if we do not want to lose /B
and are okay with having a symlink in /A
:
rm -rf /A
ln -sT /B /A # creating at /A a symlink that points to /B
However, the program could see for a short moment that /A
is missing, and crash (which one could argue is the program's fault but hopefully should not invalidate the question).
The question is how one can do this entire process of making /A
point to /B
's content, atomically, if possible.
A best-voted answer to a similar question suggests using mv -T /B /A
, which is atomic, if /A
and /B
are both symlinks. In this question, I assume /A
is originally not a symlink.
While it is easy to create a symlink to /B
using ln -sT /B link_to_B
. Following with mv -T link_to_B /A
would still not work, since /A
is still not a symlink.
Creating a link to A
with ln -sT /A link_to_A
and following with mv -T link_to_B link_to_A
does not help, since the program still points to /A
not to link_to_A
.
Is there any known solution? Thanks.
This isn't possible with regular mv
, because it's based on the rename(2)
system call, which can't atomically replace a nonempty directory. However Linux offers an extended version, renameat2(2)
, which has a RENAME_EXCHANGE
option that can atomically exchange two pathnames of any types.
There's a command-line wrapper for it on github, so you can do
rename-exchange /A /B
rm -rf /B # the former /A
Or if you'd rather end up with a symlink:
ln -s /B foo
rename-exchange /A foo
rm -rf foo