cpコマンドでコピーしたディレクトリが元のディレクトリよりも小さいのはなぜですか?


18

私は、多数のファイルがある1つのディレクトリを別の宛先にコピーすることを望んでいます。やった:

cp -r src_dir another_destination/

次に、宛先ディレクトリのサイズが元のディレクトリと同じであることを確認したかったのです。

du -s src_dir
3782288 src_dir

du -s another_destination/src_dir
3502320 another_destination/src_dir

その後、cpコマンドが続かないいくつかのシンボリックリンクがあるかもしれないと考え、-aフラグを追加しました。

-a -pPRオプションと同じです。ファイルの構造と属性を保持しますが、ディレクトリ構造は保持しません。

cp -a src_dir another_destination/

しかしdu -s、私に同じ結果を与えました。興味深いのは、ソースと宛先の両方が同じ数のファイルとディレクトリを持っていることです:

tree src_dir | wc -l
    4293

tree another_destination/src_dir | wc -l
    4293

duコマンドでさまざまなサイズを取得するのに何が間違っていますか?

更新

duコマンドで個々のディレクトリのサイズを取得しようとすると、異なる結果が得られます。

du -s src_dir/sub_dir1
1112    src_dir/sub_dir1

du -s another_destination/src_dir/sub_dir1
1168    another_destination/src_dir/sub_dir1

でファイルを表示するとls -la、個々のファイルサイズは同じですが、合計が異なります。

ls -la src_dir/sub_dir1
total 1168
drwxr-xr-x     5 hirurg103  staff     160 Jan 30 20:58 .
drwxr-xr-x  1109 hirurg103  staff   35488 Jan 30 21:43 ..
-rw-r--r--     1 hirurg103  staff  431953 Jan 30 20:58 file1.pdf
-rw-r--r--     1 hirurg103  staff  126667 Jan 30 20:54 file2.png
-rw-r--r--     1 hirurg103  staff    7386 Jan 30 20:49 file3.png

ls -la another_destination/src_dir/sub_dir1
total 1112
drwxr-xr-x     5 hirurg103  staff     160 Jan 30 20:58 .
drwxr-xr-x  1109 hirurg103  staff   35488 Jan 30 21:43 ..
-rw-r--r--     1 hirurg103  staff  431953 Jan 30 20:58 file1.pdf
-rw-r--r--     1 hirurg103  staff  126667 Jan 30 20:54 file2.png
-rw-r--r--     1 hirurg103  staff    7386 Jan 30 20:49 file3.png

1
興味深い質問。これがファイルシステムのブロックサイズになると、ソースとデスティネーションは異なるドライブ/ Iワインダーです。
davidgo

こんにちは、@ davidgo、ソースと宛先は同じドライブ上の異なるディレクトリです。ls -la結果で質問を更新しました。UPDATE
Hirurg103

2
どのファイルシステム?ディレクトリー自体が必要以上に大きい(スペースをとる)場合があります。この質問を比較してください。によって作成される新しいディレクトリcpは、必要なサイズとまったく同じです。
カミル・マシオロフスキー

ls -lsファイルが使用しているディスク容量を確認するために使用します。
バーマー

1
再帰的なmd5sumは、すべてのファイルが実際にコピーされ、内容が同じであることを確認する必要がある場合に役立ちます。rsyncは、構造とファイル全体をコピーおよび検証できる別のツールであり、ファイルの一部がすでに配置されている場合はプロセスを高速化します。
GoFundMonica-codidact.org

回答:


21

これはdu、デフォルトではファイルのサイズではなく、使用しているディスク容量が表示されるためです。-b使用されるディスク容量の合計ではなく、ファイルサイズの合計を取得するオプションを使用する必要があります。例えば:

% printf test123 > a
% ls -l a
-rw-r--r-- 1 mnalis mnalis 7 Feb  1 19:57 a
% du -h a
4,0K    a
% du -hb a
7       a

ファイルの長さはわずか7バイトですが、ディスクスペース全体で4096バイトを占有します(私の特定の例では、使用するファイルシステム、クラスターサイズなどによって異なります)。

また、一部のファイルシステムは、いわゆるスパースファイルをサポートします。このファイルは、すべてゼロのブロックにディスクスペースを使用しません。例えば:

% dd if=/dev/zero of=regular.bin bs=4k count=10
10+0 records in
10+0 records out
40960 bytes (41 kB, 40 KiB) copied, 0,000131003 s, 313 MB/s
% cp --sparse=always regular.bin sparse.bin
% ls -l *.bin
-rw-r--r-- 1 mnalis mnalis 40960 Feb  1 20:04 regular.bin
-rw-r--r-- 1 mnalis mnalis 40960 Feb  1 20:04 sparse.bin
% du -h *.bin
40K     regular.bin
0       sparse.bin
% du -hb *.bin
40960   regular.bin
40960   sparse.bin

つまり、すべてのファイルがコピーされたことを確認するには、のdu -sb代わりに使用しますdu -s


1
スパースファイルだけでなく、圧縮ファイルとインラインファイル / 常駐ファイルにより、ディスク上のサイズがファイルサイズより小さくなる
phuclv

1
そして、btrfs / zfsの奇妙な結果。
valは、

2
@val:BTRFS圧縮はdu出力に影響を与えません。長さ!=使用済みブロックの通常のアルゴリズムを使用するプログラムからは、圧縮ファイルがスパースに見えます。 btrfs.wiki.kernel.org/index.php/...
ピーター・コルド

@PeterCordesしかし、CoWのものはdu出力をかなり無意味にします。
valは、モニカを

重複ファイルはどうですか?現代のシステムは、重複したコンテンツを認識してスペースを節約できませんか?
FreeSoftwareServers

12

ディレクトリ「ファイル」のサイズが原因である可能性があります。

ほとんどのファイルシステムでは、ディスク上のディレクトリは通常のファイルによく似ており(ほとんどの場合、名前とノード番号のリストのみ)、成長するにつれてより多くのブロックを使用します。

多くのファイルを追加すると、ディレクトリ自体が大きくなります。しかし、多くのファイルシステムで後で削除しても、ディレクトリは縮小しません。

したがって、元のツリーのディレクトリの1つにある時点で多くのファイルがあり、後で削除された場合、そのディレクトリのコピーは「より小さい」ものになります。現在のファイル数に必要なブロックだけを使用するからです。

アップデートのリストには、リストしていない3つのディレクトリがあります。ls -al出力のそれら(またはそれらの子孫)のサイズを比較します。

違いがどこにあるかを見つけるには、ls -alr両方のディレクトリでを試し、ファイルにリダイレクトしてdiffから、2つの出力のいずれかを試してください。


1
別の可能性のための良いキャッチ!ただし、OPの場合、新しく作成されて最適化されるcp -a src_dir another_destination/可能性は低いですが、(過去の作成/追加からいくつかの大きなディレクトリがあった可能性がある)実際には必要以上に大きくなる可能性があります。しかし、結果は実際には小さいことを示しています()。another_destionationsrc_dirsrc_dir1112 < 1168
マティヤナリス

@MatijaNalis「更新」後の最初の例のみが(1112 <1168)であることを示しています...下の例は数字が逆になっており、最初の例もソースが大きくなっています(3782288対3502320)。おそらくOPによるタイプミス?
TripeHound

> In the listings in your update, there are 3 directories you haven't listed。実際には、ディレクトリではなくファイルです。ファイル名を参照してください > if one of the directories in your original tree had many files at some point, which were later deleted。rsyncコマンドを使用してリモートサーバーからソースディレクトリをコピーし、そこからは何も削除しませんでした
Hirurg103

1
@ Hirurg103 .エントリには、iノード上の5つのリンクが表示されます。1つは、親ディレクトリからこのディレクトリへのリンクです。別のです.。さらに3つのリンクが..あり、サブディレクトリからのリンクである必要があります。非常に奇妙なものを見逃していない限り、それらには3つのサブディレクトリが必要です。これらのリストは完全な出力であると言っていますか?
jcaron
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.