Moving a directory atomically

dirtside picture dirtside · Nov 21, 2008 · Viewed 13.9k times · Source

I have two directories in the same parent directory. Call the parent directory base and the children directories alpha and bravo. I want to replace alpha with bravo. The simplest method is:

rm -rf alpha
mv bravo alpha

The mv command is atomic, but the rm -rf is not. Is there a simple way in bash to atomically replace alpha with bravo? If not, is there a complicated way?

ADDENDUM:

By the by, it's not an insurmountable problem if the directory doesn't exist for a short period. There's only one place that tries to access alpha, and it checks if alpha exists before doing anything critical. If not, it gives an error message. But it would be nice if there was a way to do this. :) Maybe there's some way to modify the inodes directly, or something...

Answer

David Schmitt picture David Schmitt · Jun 4, 2012

The final solution is combining the symlink- and the rename-approach:

mkdir alpha_real
ln -s alpha_real alpha

# now use "alpha"

mkdir beta_real
ln -s beta_real tmp 

# atomically rename "tmp" to "alpha"
# use -T to actually replace "alpha" instead of moving *into* "alpha"
mv -T tmp alpha

Of course, the application accessing alpha has to be able to deal with symlinks changing in the path.