kích thước khối tệp - sự khác biệt giữa stat và ls


9

Tôi đã nhận thấy rằng khi tôi làm một:

ls -ls file

Nó cung cấp số khối, nói 8 khối.

Khi tôi làm:

stat file

Tôi nhận thấy rằng số khối là 16, gấp đôi số được đưa ra bởi ls.

Kích thước khối trên hệ thống tệp của tôi là 4096. Tôi đã học được rằng đơn vị tùy ý cho các khối được sử dụng bởi ls là 1024. Có đúng không khi nói rằng stat sử dụng một đơn vị 512 byte tùy ý khi báo cáo các khối?

Nếu vậy, có một lý do cho sự không nhất quán?

Tôi đang chạy Ubuntu 11.10 trên hệ thống tệp ext4.

Câu trả lời:


9

Nhiều đĩa có kích thước cung từ 512 byte, nghĩa là mọi dữ liệu đọc hoặc ghi trên đĩa đều chuyển toàn bộ cung 512 byte mỗi lần. Hoàn toàn tự nhiên khi thiết kế các hệ thống tệp trong đó một khu vực không được phân chia giữa các tệp (điều đó sẽ làm phức tạp thiết kế và làm giảm hiệu suất); do đó các hệ thống tập tin có xu hướng sử dụng các đoạn 512 byte cho các tệp. Do đó, các tiện ích truyền thống như lsduchỉ ra kích thước theo đơn vị khối 512 byte.

Đối với con người, các đơn vị 512 byte không có ý nghĩa lắm. 1kB là cùng một thứ tự cường độ và có ý nghĩa hơn rất nhiều. Một khối hệ thống tệp (đơn vị nhỏ nhất mà tệp được chia) thực sự thường bao gồm một số lĩnh vực: 1kB, 2kB và 4kB là các kích thước khối hệ thống tệp phổ biến; do đó, đơn vị 512 byte không được chứng minh mạnh mẽ bởi thiết kế hệ thống tệp và không có lý do chính đáng nào ngoài truyền thống sử dụng đơn vị 512 byte bên ngoài trình điều khiển đĩa.

Vì vậy, bạn có một truyền thống không có nhiều thứ sẽ xảy ra với nó, và một quy ước dễ đọc hơn đang diễn ra. Một chút giống như bát phân và thập lục phân: không có cái nào đúng và cái kia sai, chúng là những cách viết khác nhau cho cùng một số.

Nhiều công cụ có một tùy chọn để chọn các đơn vị hiển thị: ls --block-size=512cho GNU ls, thiết lập POSIXLY_CORRECT=1trong môi trường cho GNU dfvà GNU duđể có được các đơn vị 512 byte (hoặc chuyển -ksang các đơn vị 1kB). Những gì statlệnh trong GNU coreutils thể hiện là kích thước khối của bộ điều khiển ( %Bgiá trị) là một giá trị phụ thuộc hệ điều hành của giao diện bên trong; tùy thuộc vào HĐH, nó có thể có hoặc không liên quan đến kích thước được sử dụng bởi hệ thống tập tin hoặc mã đĩa (thường là không - xem Sự khác biệt giữa kích thước khối và kích thước cụm ). Trên Linux, giá trị là 512, bất kể trình điều khiển cơ bản nào đang làm gì. Giá trị của %Bkhông bao giờ quan trọng, nó chỉ là một sự châm biếm rằng nó tồn tại.


4

Sau khi đào sâu vào mã nguồn và tiêu chuẩn POSIX, tôi sẽ nói câu trả lời của @ antje-m và @Gilles là chính xác.

Thật đáng để trích dẫn nhận xét từ POSIX.1-2008 , như một bản tóm tắt:

Việc sử dụng các đơn vị 512 byte là thông lệ lịch sử và duy trì khả năng tương thích với ls và các tiện ích khác trong tập POSIX.1-2008 này. Điều này không bắt buộc rằng chính hệ thống tệp phải dựa trên các khối 512 byte. Tùy chọn -k đã được thêm vào như một biện pháp thỏa hiệp. Các nhà phát triển tiêu chuẩn đã đồng ý rằng 512 byte là đơn vị mặc định tốt nhất vì tính nhất quán lịch sử hoàn chỉnh của nó trên Hệ thống V (so với việc sử dụng 512/1024 byte hỗn hợp trên các hệ thống BSD) và tùy chọn -k để chuyển sang 1024- đơn vị byte là một sự thỏa hiệp tốt. Người dùng thích số lượng 1024 byte hợp lý hơn có thể dễ dàng đặt bí danh df thành df -k mà không phá vỡ nhiều tập lệnh lịch sử dựa trên các đơn vị 512 byte.

Đối với kích thước khối trong ls -s:

POSIX nói rằng kích thước khối mặc định được xác định theo triển khai, trừ khi -kđược cung cấp tùy chọn.

Kích thước khối mặc định được triển khai trong GNU coreutils lsđược xác định trong GNU gnulib: gnulib/lib/human.c

/* The default block size used for output.  This number may change in
   the future as disks get larger.  */
#ifndef DEFAULT_BLOCK_SIZE
# define DEFAULT_BLOCK_SIZE 1024
#endif

xuất phát từ một cam kết cũ:

commit 96e78d1f64d7c8d2acc5ad27dc3e73b96ae80585
Author: Jim Meyering <jim@meyering.net>
Date:   Mon Jun 29 15:23:04 1998 +0000

Bản thân thông điệp cam kết không nói gì về số 1024.

Và lưu ý rằng kích thước khối được sử dụng trong dudfcũng là 1024, lschỉ cần chọn để phù hợp với chúng. Mặc dù dudfđó là một mâu thuẫn với tiêu chuẩn POSIX (vì vậy ở đây có biến môi trường POSIXLY_CORRECT). Đây có vẻ là một quyết định của nhóm GNU, xem trang POSIX của wikipedia về tranh cãi này.

Đối với lệnh stat.

Nó không phải là một phần của tiêu chuẩn POSIX, nhưng cuộc gọi hệ thống là. Tuy nhiên, đơn vị cho kích thước khối không được tiêu chuẩn hóa ( sys_stat.h ):stat

Đơn vị cho thành viên st_blocks của cấu trúc stat không được xác định trong POSIX.1-2008.

Các statlệnh đơn giản hiển thị thông tin được cung cấp bởi statcuộc gọi hệ thống, và sử dụng 512 Kích thước khối với vài ngoại lệ (họ đều là phòng không Linux, ví dụ như HP-UX, IBM AIX, vv thấy các macro quy định tại gnulib/lib/stat-size.h).

Vì vậy, số 512 là một sự lựa chọn lịch sử và một quy ước của Linux.

Các GNU coreutils(do đó lslệnh) không phải là một phần của Linux kernel (do đó statgọi), họ đang nhắm mục tiêu khía cạnh hệ thống khác nhau, GNU coreutilsđược nhiều hơn cho con người (dễ đọc), và Linux kernel cho phần cứng trừu tượng (do đó gần gũi hơn với phần cứng).

Chỉnh sửa: kích thước khối 4096 là kích thước "Khối IO", kích thước khối vật lý thực có khả năng vẫn là 512 Byte như được giải thích trong câu hỏi này .


1

Các statlệnh sử dụng kích thước khối vật lý của đĩa cứng. Về cơ bản tất cả các đĩa cứng kể từ khi thành lập năm 1956 đã sử dụng các khối 512 byte. Tuy nhiên, điều này gần đây đã bắt đầu thay đổi với định dạng nâng cao sắp tới.

Tôi nghi ngờ rằng ls'1024byte-blocksize cũng có một lý do lịch sử. Có lẽ nó đã từng phổ biến đối với hệ thống tập tin có kích thước khối 1024 hoặc nó được sử dụng để cung cấp cho bạn kích thước tính bằng kilobyte. Nhưng (ít nhất là với GNU coreutils) bạn có thể chỉ định kích thước khối với --block-size=tùy chọn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.