Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Moving a directory atomically

Tags:

linux

bash

atomic

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...

like image 972
dirtside Avatar asked Nov 21 '08 00:11

dirtside


People also ask

How do I move a folder to another directory?

Select the directory you want to move and press Ctrl+X. Alternatively, right-click the directory and select Cut from the drop-down menu. 2. Navigate to the destination and press Ctrl+V or right-click the empty space and select Paste from the drop-down menu to move the directory.

What is the general syntax for moving a directory?

The mv (move) command is used to move one or more files or directories from one directory to another directory using terminal in the Linux/Unix operating system. After using the mv command file is copied from source to destination and source file is removed. The mv command is also used to rename the file.

How do I move a folder in Shell?

To move a file or directory from one location to another, use the command mv. Common useful options for mv include: -i (interactive) — Prompts you if the file you have selected overwrites an existing file in the destination directory. -f (force) — Overrides the interactive mode and moves without prompting.

Is move file an atomic?

As long as it is a move within one file system, the size of the files to move should be irrelevant (only the directory files concerned are changed). No. But the move of each induvidual file is atomic.


2 Answers

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.

like image 72
David Schmitt Avatar answered Sep 23 '22 02:09

David Schmitt


You can do this if you use symlinks:

Let's say alpha is a symlink to directory alpha_1, and you want to switch the symlink to point to alpha_2. Here's what that looks like before the switch:

$ ls -l lrwxrwxrwx alpha -> alpha_1 drwxr-xr-x alpha_1 drwxr-xr-x alpha_2 

To make alpha refer to alpha_2, use ln -nsf:

$ ln -nsf alpha_2 alpha $ ls -l lrwxrwxrwx alpha -> alpha_2 drwxr-xr-x alpha_1 drwxr-xr-x alpha_2 

Now you can remove the old directory:

$ rm -rf alpha_1 

Note that this is NOT actually a fully atomic operation, but it does happen very quickly since the "ln" command both unlinks and then immediately recreates the symlink. You can verify this behaviour with strace:

$ strace ln -nsf alpha_2 alpha ... symlink("alpha_2", "alpha")             = -1 EEXIST (File exists) unlink("alpha")                         = 0 symlink("alpha_2", "alpha")             = 0 ... 

You can repeat this procedure as desired: e.g. when you have a new version, alpha_3:

$ ln -nsf alpha_3 alpha $ rm -rf alpha_2 
like image 23
Doug Currie Avatar answered Sep 22 '22 02:09

Doug Currie