Перемещение каталога атомарно - PullRequest
32 голосов
/ 21 ноября 2008

У меня есть два каталога в одном родительском каталоге. Вызовите родительский каталог base и дочерние каталоги alpha и bravo . Я хочу заменить alpha на bravo . Самый простой способ:

rm -rf alpha
mv bravo alpha

Команда mv является атомарной, но команда rm -rf - нет. Есть ли в bash простой способ атомарной замены alpha на bravo ? Если нет, то есть ли сложный путь?

ДОПОЛНЕНИЕ:

Кстати, это не является непреодолимой проблемой, если каталог не существует в течение короткого периода времени. Есть только одно место, которое пытается получить доступ к альфе, и оно проверяет, существует ли альфа, прежде чем делать что-либо критическое. Если нет, то выдает сообщение об ошибке. Но было бы неплохо, если бы был способ сделать это. :) Может быть, есть какой-то способ изменить иноды напрямую или что-то в этом роде ...

Ответы [ 15 ]

0 голосов
/ 12 января 2018

Также возможно заменить целые части содержимого сразу в некотором префиксе (Z здесь), используя unionfs-fuse:

# mkdir a b c Z
# touch a/1 b/2 c/3
# ln -s a X
# ln -s b Y
# unionfs X=RW:Y=RW Z
# shopt -s globstar
# file **
a:   directory
a/1: empty
b:   directory
b/2: empty
c:   directory
c/3: empty
X:   symbolic link to a
Y:   symbolic link to b
Z:   directory
Z/1: empty
Z/2: empty
# ln -sfn c Y
# file **/*
a:   directory
a/1: empty
b:   directory
b/2: empty
c:   directory
c/3: empty
X:   symbolic link to a
X/1: empty
Y:   symbolic link to c
Y/3: empty
Z:   directory
Z/1: empty
Z/3: empty
# fusermount -u Z
# rm -r a b c X Y Z
0 голосов
/ 16 ноября 2009

mv и ln могут быть использованы для атомарных операций. Я использовал ln (1) для атомного развертывания веб-приложений.

Правильный способ заменить символическую ссылку - ln -nsf

ln -nsf <target> <link_name>

, например

$ mkdir dir1
$ mkdir dir2
$ ln -s dir1 mylink
$ ls -l mylink
lrwxrwxrwx  1 phil phil 4 Nov 16 14:45 mylink -> dir1
$ ln -nsf dir2 mylink
$ ls -l mylink
lrwxrwxrwx  1 phil phil 4 Nov 16 14:46 mylink -> dir2
0 голосов
/ 21 ноября 2008

Почему бы вам просто не сделать что-то вроде:

rm -rf alpha/*
mv bravo/* alpha/
rm -rf bravo/

Это означало бы, что все в альфа уничтожено, альфа никогда не удаляется, а все содержимое перемещается.

0 голосов
/ 21 ноября 2008

Следует помнить, что если у вашего процесса какие-либо файлы в альфа-режиме открыты, когда происходит это перемещение / удаление, процесс не заметит, и любые записанные данные будут потеряны, когда файл будет закрыт и окончательно удален.

0 голосов
/ 21 ноября 2008

Я не верю, что есть какой-то атомарный способ сделать это. Лучше всего сделать что-то вроде этого:

mv alpha delme
mv bravo alpha
rm -rf delme
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...