Mengapa ls-l menampilkan ukuran yang berbeda dari ls -s?

38

Saya tidak tahu mengapa saya mendapatkan hasil berikut:

ls -l memberi tahu saya ukuran file yang diberikan (SEJARAH) adalah "581944":

$ ls -l HISTORY 
-rw-rw-r-- 1 waldyrious waldyrious 581944 Feb 22 10:59 HISTORY

ls -s mengatakan itu "572":

$ ls -s HISTORY
572 HISTORY

Saya jelas perlu membuat nilai menggunakan skala yang sebanding. Jadi pertama-tama saya mengkonfirmasi bahwa menggunakan --block-size 1di ls -lmemberi saya hasil yang sama seperti sebelumnya:

$ ls -l --block-size 1 HISTORY 
-rw-rw-r-- 1 waldyrious waldyrious 581944 Feb 22 10:59 HISTORY

Lalu saya melakukan hal yang sama ls -suntuk mendapatkan nilai dalam skala yang sama:

$ ls -s --block-size 1 HISTORY 
585728 HISTORY

Hasil yang berbeda! 581944 ≠ 585728 .

Saya mencoba menghasilkan nilai yang sebanding sebaliknya, menggunakan -k, tetapi saya mendapatkan:

$ ls -lk HISTORY 
-rw-rw-r-- 1 waldyrious waldyrious 569 Feb 22 10:59 HISTORY
$ ls -sk HISTORY 
572 HISTORY

Sekali lagi, hasil yang berbeda, 569 ≠ 572 .

Saya mencoba menentukan --si untuk memastikan kedua opsi menggunakan skala yang sama, tetapi tidak berhasil:

$ ls -lk --si HISTORY 
-rw-rw-r-- 1 waldyrious waldyrious 582k Feb 22 10:59 HISTORY
$ ls -sk --si HISTORY 
586k HISTORY

... sekali lagi, nilai yang berbeda: 582k ≠ 586k .

Saya mencoba mencari di web tetapi satu-satunya hal yang saya temukan yang tampaknya relevan adalah ini :

Beberapa file memiliki "lubang" di dalamnya, sehingga penggunaan yang terdaftar oleh ls -s(...) kurang dari ukuran file yang terdaftar oleh ls -l. "

(perhatikan bahwa dalam hasil saya yang sebaliknya terjadi: ls -smengembalikan ukuran lebih besar dari ls -l, tidak lebih kecil.)

Sementara itu, halaman ini mengatakan itu

tidak ada cara yang elegan untuk mendeteksi lubang file Unix.

Jadi, bagaimana saya bisa mengatasi perbedaan ini? Manakah dari nilai-nilai ini yang dapat dianggap benar? Mungkinkah ini bug di dalamnya ls?

waldyrious
sumber

Jawaban:

47

Jawaban singkat:

  • ls -l memberikan ukuran file (= jumlah data yang dikandungnya)
  • ls -s --block-size 1 memberikan ukuran file pada sistem file

Mari kita membuat dua file:

Sebuah file jarang dari 128 byte panjang (A file jarang adalah file yang berisi blok kosong, lihat Jarang Berkas ):

# truncate -s 128 f_zeroes.img
# hexdump -vC f_zeroes.img 
00000000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000050  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000060  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000070  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000080

File lain dengan data acak, juga ukuran 128 byte:

# dd if=/dev/urandom of=f_random.img bs=1 count=128
# hexdump -vC f_random.img 
00000000  bc 82 9c 40 04 e3 0c 23  e6 76 79 2f 95 d4 0e 45  |...@...#.vy/...E|
00000010  19 c6 53 fc 65 83 f8 58  0a f7 0e 8f d6 d6 f8 b5  |..S.e..X........|
00000020  6c cf 1b 60 cb ef 06 c6  d0 99 c6 16 3f d3 95 02  |l..`........?...|
00000030  85 1e b7 80 27 93 27 92  d0 52 e8 72 54 25 4d 90  |....'.'..R.rT%M.|
00000040  11 59 a2 d9 0f 79 aa 23  2d 44 3d dd 8d 17 d9 36  |.Y...y.#-D=....6|
00000050  f5 ae 07 a8 c1 b4 cb e1  49 9e bc 62 1b 4f 17 53  |........I..b.O.S|
00000060  95 13 5a 1c 2a 7e 55 b9  69 a5 50 06 98 e7 71 83  |..Z.*~U.i.P...q.|
00000070  5a d0 82 ee 0b b3 91 82  ca 1d d0 ec 24 43 10 5d  |Z...........$C.]|
00000080

Jadi, seperti yang Anda lihat dalam representasi hex, kedua file memiliki jumlah data yang sama , meskipun kontennya sangat berbeda.

Sekarang, mari kita lihat direktori:

# ls -ls --block-size 1 f_*
1024 -rw-r--r-- 1 user user 128 Mar 18 15:34 f_random.img
   0 -rw-r--r-- 1 user user 128 Mar 18 15:32 f_zeroes.img
   ^                         ^
   |                         |
Amount which the           Actual file size
files takes on the fs

Nilai pertama diberikan oleh -s --block-size 1opsi, itu adalah jumlah ruang yang digunakan oleh file pada sistem file .

Seperti yang Anda lihat, file jarang memakan ruang nol, karena sistem file ( ext3dalam hal ini) cukup pintar untuk mengenali bahwa itu hanya berisi nol. Juga, file dengan data acak membutuhkan 1024 byte pada disk!

Nilai tergantung pada bagaimana sistem file yang mendasarinya memperlakukan file (ukuran blok, kemampuan file jarang, ...).

Di kolom keenam adalah ukuran file jika Anda akan membacanya - itu adalah jumlah data yang terkandung di dalamnya dan 128 byte untuk kedua file!

phoibos
sumber
1
Agaknya, bahkan file kosong atau file yang penuh dengan nilai nol akan memakan tempat di tabel alokasi file di suatu tempat? Kenapa tidak ls -sdihitung?
Flimm
2
Metadata tentang file disimpan dalam inode. Setiap sistem file memiliki jumlah inode terbatas yang dapat digunakan. Untuk melihat berapa banyak inode gratis yang dimiliki sistem file dan ukurannya:, sudo tune2fs -l /dev/sdaX|grep Inodeatau df -iuntuk semua partisi.
phoibos
1
Saya baru saja menemukan cara yang menarik dan tidak buatan untuk memverifikasi ini: file torrent .part tampaknya menjadi contoh yang baik dari file berlubang: ls -lsh ~/Downloads/torrentsberi saya, misalnya 92K -rw-r--r-- 1 waldir waldir 350M Sep 15 2012 video.avi.part,. Yaitu, 92K, yang dikembalikan oleh opsi -s, adalah ruang aktual dari file yang diambil, filesystem-wise, dan 350M, dikembalikan oleh opsi -l, adalah ukuran penuh file yang akan dimiliki jika itu sepenuhnya diunduh (yaitu jika semua byte, dari awal hingga selesai, tidak nol). Lihat lists.freebsd.org/pipermail/freebsd-questions/2012-June/…
waldyrious
14

ls -smemberi tahu Anda ukuran file yang dialokasikan , selalu kelipatan dari unit alokasi. ls -lmemberitahu ukuran sebenarnya. Cara mudah untuk menguji:

$ echo 1 > sizeTest
$ ls -l --block-size 1 sizeTest 
-rw-rw-r-- 1 g g 2 Mär 18 15:18 sizeTest
$ ls -s --block-size 1 sizeTest 
4096 sizeTest
Guntbert
sumber