Динамическое объединение содержимого нескольких каталогов - это как раз то, о чем union mount (или объединенная файловая система). В Linux существует несколько реализаций, но обычные решают дублирование между ветвями, всегда предпочитая одну конкретную ветвь (например, dir2 / file
всегда имеет приоритет над dir1 / file
, если оба существуют). Однако я только что обнаружил mergerfs , который имеет более гибкие политики и, в частности, позволяет выбирать самый новый файл для каждого файла отдельно.
Установка:
mkdir dir1 dir2 merge
echo 1 >dir1/b; echo 2 >dir2/a
sleep 1
echo 1 >dir1/a; echo 2 >dir2/b; echo 2 >dir2/c
Теперь монтируем. Мы устанавливаем новейшую
политику для доступа к файлам ( поиск
) и изменения метаданных ( действие
), а также запрещаем создание ( create
) (вы может передать создание одной из ветвей, всегда одной и той же, или в зависимости от доступного дискового пространства, или даже случайным образом!).
$ mergerfs -o category.action=newest,category.search=newest,category.create=erofs dir1:dir2:dir3 merge
$ head merge/?
==> merge/a <==
1
==> merge/b <==
2
==> merge/c <==
2
$ rm dir2/c
$ echo merge/?
a b
Чтобы отключить: fusermount -u merge
Используйте ln
для создания символических ( -s
) ссылок, которые позволяют использовать несколько указателей на один и тот же фактический файл. ответьте на ваш главный вопрос. Однако ваш пример использования автоматического добавления теперь соответствует этому (но это может быть полезно для других, читающих ваш заголовок и заголовок).
ln -s src/of/actual/file merge_directory/pointer_link
Это мой хак с использованием bash. Недостатком решения является то, что во время выполнения скрипта он создает симлинки для каждой копии, но поскольку последнее имя файла (с тем же именем) является именем с самой новой временной меткой, симлинк на него останется.
Перед запуском скрипта обязательно измените переменные MDIR (merge dir) и BDIR (начальный каталог/каталоги).
MDIR=/tmp
(
BDIR="/tmp/ssh /etc/ssh"
for entry in $(find $BDIR -type f -exec stat --printf "%n,%Y\n" {} \;);do
fname=$(echo $entry | cut -f 1 -d ,)
tstamp=$(echo $entry | cut -f 2 -d ,)
bname=$(basename $fname)
echo $bname,$fname,$tstamp
done
) | sort -t, -nk 3 | \
while read entry;do
bname=$(echo $entry | cut -f 1 -d ,)
fname=$(echo $entry | cut -f 2 -d ,)
tstamp=$(echo $entry | cut -f 3 -d ,)
ln -svf $fname $MDIR/$bname
done