dir1
たとえば、dir2
...などの特定の数のソースディレクトリがある場合、ソースdir5
ディレクトリ内のすべてのファイルとディレクトリが含まれているが重複ファイルは含まれない、自動的に同期された「マージ」ターゲットディレクトリをどのように作成できますか?
たとえば、次のようなソースディレクトリ構造があります。
dir1/
- a
- b
dir2/
- b <-- Note the duplicate name, this one is more recent than dir1\b
- c
- dir2.1/ <-- Subdirectories present too.
- z
dir3/
- d
..."マージ"すると、次のようになります。
merge/
- dir2.1/
- z
- a
- b <-- Which one to show is based on modified time; most recent first.
- c
- d
(何千ものファイルとサブディレクトリを含む数十のディレクトリがあるとします。)
ソースリスト内のすべてのファイルとディレクトリはそのままにしておく必要があり、「マージされた」ターゲットディレクトリは追加のストレージを占有しないでください。つまり、inotifyを使用して、一部のデーモンが管理するすべてのシンボリックリンクにすることができます。さらに、ソースディレクトリはファイルとサブディレクトリを頻繁に追加および削除します。これはできるだけ早く「マージされた」ディレクトリに反映する必要があります。
いくつかの使用例:
新しいファイルを作成すると、dir3/e
すぐに(または数秒以内に)ディレクトリに自動的に表示されますmerge
。
ファイルを削除すると、すぐに(または数秒以内に)ディレクトリからdir1/a
自動的に消えます。merge
dir3/d
開いて編集します。merge/d
更新された修正日を持つように呼び出しているtouch
ため、最新の日付を指すように自動的に更新されます。dir1/b
dir2/b
merge/b
dir1/b
私はそれを削除し、dir1/b
今はmerge/b
古いファイルをポイントしますdir2/b
。
その中にファイルを作成しようとしましたが、merge
意味がないのでエラーが発生しました!
答え1
複数のディレクトリの内容を動的に結合するのは正確です共同設置(またはUnion File System)についてです。 Linuxにはさまざまな実装がありますが、一般的な実装は常に1つの特定のブランチを優先し、ブランチ間の重複を解決します(たとえば、両方が存在する場合はdir2/file
常に優先順位がありますdir1/file
)。しかし、私は今知っていました。ファイルシステムのマージ特に、ファイルごとに最新のファイルを選択できるより柔軟なポリシーがあります。
設定:
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
今私たちはバスに乗りました。newest
ファイルアクセス(search
)とメタデータの変更()action
のポリシーを設定し、作成を許可しません(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
答え2
これはbashを使って修正したものです。このソリューションの欠点は、スクリプトの実行中に各コピーごとにシンボリックリンクを作成しますが、(同じ名前を持つ)最後のファイル名が最新のタイムスタンプを持つファイルであるため、そのファイルを指すシンボリックリンクが予約されていることです。
実行する前に、マージディレクトリ(MDIR)と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
答え3
ln
複数のポインタが同じ物理ファイルを指すようにするシンボル()リンクの作成を使用すると、主な-s
質問に答えることができます。しかし、今はautoaddの使用例で十分です(しかし、あなたのタイトルとタイトルを読んでいる他の人にとっては便利です)。
ln -s src/of/actual/file merge_directory/pointer_link