各ファイルが元のファイルへのハードリンクであるディレクトリツリーの「コピー」を作成したい
例:私はディレクトリ構造を持っています:
dirA/
dirA/file1
dirA/x/
dirA/x/file2
dirA/y/
dirA/y/file3
期待される結果、各ファイルが元のファイルへのハードリンクであるディレクトリツリーの「コピー」は次のとおりです。
dirB/ # normal directory
dirB/file1 # hardlink to dirA/file1
dirB/x/ # normal directory
dirB/x/file2 # hardlink to dirA/x/file2
dirB/y/ # normal directory
dirB/y/file3 # hardlink to dirA/y/file3
Linux(より正確には、GNUとbusybox
のcp
の実装で、Linuxをカーネルとして持つシステムで通常見られる)と最近のFreeBSDでは、これはどうやって:
cp -al dirA dirB
よりポータブルなソリューションについては、StéphaneChazelasによるpaxとcpioを使用した回答を参照してください
POSIXlyの場合、pax
を読み取りと書き込みモードで-l
オプションを指定して使用します。
pax -rwlpe -s /A/B/ dirA .
(-pe
は、GNU cp
の-a
のように)コピーされるファイル(この場合はディレクトリのみ)のすべての可能な属性を保持します。
標準ですが、そのコマンドは必ずしもportableとは限りません。
まず、多くのGNU/Linuxベースのシステムには、デフォルトでpax
が含まれていません(これはオプションのPOSIXユーティリティではありません)。
次に、いくつかのバグといくつかの実装の不適合により、そのコードで多くの問題が発生します。
pax
(少なくとも)は、-rwl
と-s
を組み合わせて使用すると機能しません。何らかの理由で、元のパスとコピーされたパスの両方に置換が適用されているようです。したがって、上記ではlink("dirB/file", "dirB/file")
の代わりにlink("dirA/file", "dirB/file")
を実行しようとします。pax
はタイプsymlinkのファイルのハードリンクを作成しません(POSIXで許可されている動作)。それだけでなく、置換をシンボリックリンクのターゲットにも適用します(動作not POSIXで許可されています)。たとえば、dirA
にfoo -> AA
シンボリックリンクがある場合、それはdirB
でfoo -> BA
になります。また、同じことをしたいが、$src
と$dst
にコンテンツが格納されている任意のファイルパスを使用する場合は、pax -rwl -- "$src" "$dst"
が$src
内に$dst
の完全なディレクトリ構造を作成することを理解することが重要です(存在する必要があり、ディレクトリである必要があります)。たとえば、$src
がfoo/bar
の場合、$dst/foo/bar
が作成されます。
代わりに、$dst
を$src
のコピーにしたい場合は、おそらく次のようにするのが最も簡単です。
absolute_dst=$(umask 077 && mkdir -p -- "$dst" && cd -P -- "$dst" && pwd -P) &&
(cd -P -- "$src" && pax -rwlpe . "$absolute_dst")
(これはまた、上記の問題のほとんどを回避しますが、$dst
の絶対パスが改行文字で終わる場合は失敗します)。
これは、pax
がないGNU/Linuxシステムでは役に立ちません。
興味深いのは、pax
がtar
コマンドとcpio
コマンドの機能をマージするためにPOSIXによって作成されたことです。
cpio
は、POSIXの発明とは対照的にhistorical Unixコマンド(1977年から)であり、GNUの実装もあります(pax
one)。したがって、もはやstandardコマンドではありませんが(SUSv2にありました)、それは非常に一般的であり、通常は信頼できるコア機能のセットがありますオン。
pax -rwl
に相当するものはcpio -pl
です。しかしながら:
cpio
は、引数ではなくstdinの入力ファイルのリストを取ります(改行で区切られているため、改行文字を含むファイル名はサポートされていません)。find
の出力をフィードします(find
とcpio
は同じ人が共同で開発しました))。cpio
実装には、一部を保持するオプションがありますが、移植性はありません)。cpio
の場合:
absolute_dst=$(umask 077 && mkdir -p -- "$dst" && cd -P -- "$dst" && pwd -P) &&
(cd -P -- "$src" && find . | cpio -pl "$absolute_dst")
簡潔な答え:
cd $source_folder
pax -rwlpe . $dest_folder
あなたがそのファイルを探している場合ハードリンクのコピー機能を使用して、ファイルの(すべてまたは一部の)バックアップのスナップショットを作成し、rsnapshot
を確認します。
@ gudmundur-ornの答えは正しいですが、LinuxでBtrFSを使用している場合はcp a --reflink=auto dirA dirB
でうまくいくはずですが、ファイルが実際に異なり、一方を変更しても他方は変更されません。 APFSを搭載したMacでcp -c
を使用すると、ほとんど同じことができます(不可能な場合、auto
は完全なコピーを実行し、-c
は失敗します)。
どのCOWファイルシステムでもこれを実行できるはずですが、ベンダーは標準のコマンドラインオプションについて合意していません。