Số lượng byte của các ls-l <tập tin ngẫu nhiên> so với của tập tin wc -c <tập tin ngẫu nhiên>


25

Có tình huống nào xảy ra khi

ls -l file.txt

đang hiển thị không cùng số byte như

wc -c file.txt

Trong một kịch bản, tôi thấy so sánh hai giá trị đó. Điều gì có thể là lý do của điều đó? Thậm chí có thể có số byte khác nhau của cùng một tệp không?


2
Bạn có thể đưa ra một số bối cảnh cho kịch bản này mà bạn tìm thấy?
Kusalananda

Câu trả lời:


13

Vâng, có những trường hợp như vậy.

Trong trường hợp liên kết tượng trưng trên hệ thống Linux với GNU ls, ls -lsẽ đưa ra kích thước của liên kết, trong khi wc -csẽ giải quyết tệp thực tế và đọc số byte ở đó. Dưới đây bạn có thể thấy rằng ls -lbáo cáo 29 byte, trong khi wcbáo cáo 172 byte trong tệp thực tế.

$ ls -l /etc/resolv.conf                                                                                                 
lrwxrwxrwx 1 root root 29 1月  17  2016 /etc/resolv.conf -> ../run/resolvconf/resolv.conf
$ wc -c /etc/resolv.conf                                                                                                 
172 /etc/resolv.conf
$ wc -c /var/run/resolvconf/resolv.conf                                                                                  
172 /var/run/resolvconf/resolv.conf
$ ls -l /var/run/resolvconf/resolv.conf                                                                                  
-rw-r--r-- 1 root root 172 1月  15 15:49 /var/run/resolvconf/resolv.conf

Trong trường hợp hệ thống tệp ảo , chẳng hạn như/proc hoặc /sys, nhiều tệp ở đó sẽ hiển thị là có kích thước 0 ls -l. Trong /devhệ thống tệp, chúng tôi có nhiều tệp đặc biệt, chẳng hạn như thiết bị ký tự và thiết bị khối - wc -ctreo trên đó và ls -lhiển thị số lớn và số nhỏ thay vì kích thước.

Các đường ống được đặt tên sẽ được báo cáo là 0byte theo ls -c, nhưng wc -cthực tế sẽ đọc nội dung của đường ống, vì vậy về mặt kỹ thuật, nó sẽ cho bạn biết có bao nhiêu dữ liệu trong đường ống được đặt tên:

$ mkfifo named.pipe                                                                                                      
$ echo "This is a test" > named.pipe &
[1] 2129
$ ls -l named.pipe
prw-rw-r-- 1 xieerqi xieerqi 0 1月  16 08:40 named.pipe|
$ wc -c named.pipe
15 named.pipe
[1] + Done                 echo "This is a test" >named.pipe 

Đối với một tệp thông thường, kích thước phải bằng nhau.


Điểm của ls -lwc -c, và cách họ làm việc cũng khác nhau. wc -cthực sự mở tệp để đọc (bạn có thể thấy rằng nếu bạn chạy strace wc -c /etc/passwdchẳng hạn). ls -lchỉ thực hiện stat()cuộc gọi trên những. Điều này cũng giải thích tại sao trong /proc ls -lhiển thị kích thước 0 - bạn không thể thống kê các tệp đó vì chúng không "thực" hoặc thực sự được lưu trữ trên ổ cứng / ssd. wc -cthay vào đó, đọc nội dung của tệp đó và tính kích thước của nó.

Cuối cùng, ls -lchỉ là một công cụ để liệt kê các mục tương tác. Nó hiếm khi phù hợp để viết kịch bản. Khi bạn thực sự cần đọc dữ liệu, sử dụng wc -cthay thế.

Xin lưu ý rằng đối với kịch bản và đánh giá kích thước của tệp, lskhông phải là ứng cử viên tốt nhất. Trong thực tế, đó là một trong những thực tiễn phổ biến để tránh phân tích cú pháp lsđầu ra . Vui lòng sử dụng du -b để tìm ra kích thước của một tập tin.


1
Một giải thích nhỏ - file ảo (trong /sys/, /proc/, vv) có thể cung cấp statthông tin, nếu chọn nhóm người thực hiện để. Hầu hết thời gian, không có lý do thuyết phục nào, vì vậy nó bị bỏ qua. Các ví dụ bao gồm /proc/kcoređược báo cáo là kích thước của bộ nhớ kernel có thể định địa chỉ (thường nhiều hơn bộ nhớ vật lý khả dụng).
Toby Speight

11

ls -l sẽ trả về kích thước của tệp được báo cáo bởi hệ thống tệp.

wc -csẽ cố đọc tệp để xác định kích thước 'thực tế'. Từ những quan sát của tôi, lần đầu tiên nó dường như cố gắng tìm kiếm đến cùng, và nếu điều này không hoạt động, nó sẽ đọc toàn bộ tập tin, đếm kích thước khi nó đi.

Đây là một mô tả đơn giản về những gì hai công cụ làm, nhưng nó dẫn đến một số hàm ý cho kết quả:

lssẽ đưa ra một đầu ra không chính xác cho các hệ thống tập tin nhất định. Ví dụ: các hệ thống tệp ảo như /procsẽ báo cáo kích thước bằng 0 cho nhiều tệp, vì các "tệp" này không được lưu trữ ở bất kỳ đâu; chúng được tạo ra theo yêu cầu của phần mềm.

wcsẽ hoàn toàn không hoạt động đối với các tệp mà không có quyền đọc, trong khi lschỉ yêu cầu quyền liệt kê thư mục (so sánh ls -l /etc/shadowvới wc -c /etc/shadow).

Như đã đề cập trong các câu trả lời khác, hành vi cho các liên kết tượng trưng cũng khác nhau. Bởi vì wccố gắng đọc chúng, cuối cùng nó đọc tệp mà symlink trỏ tới, trong khi vì lschỉ truy vấn hệ thống tệp, nó sẽ báo cáo kích thước được sử dụng để lưu trữ chính liên kết tượng trưng.

Tôi chắc chắn có những khác biệt khác mà tôi chưa nghĩ đến, nhưng tôi nghĩ tôi sẽ đưa ra một lời giải thích rõ ràng và đơn giản về lý do cơ bản đằng sau những khác biệt này.


+1 để đề cập đến quyền đọc và seek(). Điều này dường như là trường hợp, sau khi chạy strace wc -ltrên một vài tệp lớn.
Sergiy Kolodyazhnyy

+1 để thêm nhiều chi tiết hơn câu trả lời của tôi!
Cyclic3

6

Đối với một tập tin bình thường, ls và wc gọi stat. Tuy nhiên, đối với tệp / Proc hoặc / sys, ls trả về 0, nhưng wc trả về một số khác:

$ ls -l /proc/modules
-r--r--r--  1 root root 0 Jan 16 14:56 modules
                        ^ this one
$ wc -c /proc/modules
7621 modules

Đây có lẽ là một số cách để tìm hiểu nếu một cái gì đó là một tập tin đặc biệt.


2
wc -cđối với tôi ít nhất là gọi fstat, nhưng dường như cho các mục đích khác. Nó tìm thấy chiều dài của tập tin bằng cách lseeking đến cuối. Trong trường hợp điều này trả về một lỗi, đó readlà toàn bộ tệp.
Muzer
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.