Hitungan byte "ls -l <file acak>" dibandingkan dengan "wc -c <file acak>"

25

Apakah ada situasi yang memungkinkan ketika

ls -l file.txt

tidak menunjukkan jumlah byte yang sama dengan

wc -c file.txt

Dalam satu skrip saya menemukan perbandingan kedua nilai tersebut. Apa yang bisa menjadi alasan itu? Apakah mungkin untuk memiliki jumlah byte yang berbeda dari file yang sama?

Rokas.ma
sumber
2
Bisakah Anda memberikan konteks pada skrip ini yang Anda temukan?
Kusalananda
Lihat juga unix.stackexchange.com/a/321502/22565
Stéphane Chazelas

Jawaban:

13

Ya, ada beberapa kasus seperti itu.

Dalam kasus symlink pada sistem Linux dengan GNU ls, ls -lakan mengeluarkan ukuran tautan, sementara wc -cakan menyelesaikan file aktual dan membaca jumlah byte di sana. Di bawah ini Anda dapat melihat bahwa ls -llaporan 29 byte, sedangkan wclaporan 172 byte di file yang sebenarnya.

$ 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

Dalam hal sistem file virtual , seperti/proc atau /sys, banyak file di sana akan menunjukkan memiliki ukuran 0 ls -l. Di bawah /devsistem file, kami memiliki beragam file khusus, seperti perangkat karakter dan perangkat blok - wc -cmenggantungnya dan ls -lmenunjukkan angka-angka besar dan kecil alih-alih ukuran.

Pipa yang dinamai akan dilaporkan sebagai 0byte oleh ls -c, tetapi wc -csebenarnya akan membaca isi pipa, jadi secara teknis akan memberi tahu Anda berapa banyak data dalam pipa bernama:

$ 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 

Untuk file biasa, ukurannya harus sama.


Titik ls -ldan wc -c, dan cara kerjanya juga berbeda. wc -csebenarnya membuka file untuk dibaca (Anda dapat melihat bahwa jika Anda menjalankan strace wc -c /etc/passwdmisalnya). ls -lhanya melakukan stat()panggilan pada mereka. Ini juga menjelaskan mengapa dalam /proc ls -lmenunjukkan ukuran 0 - Anda tidak dapat membuat stat file-file itu karena mereka tidak "asli" atau benar-benar disimpan pada hard-drive / ssd. wc -calih-alih, baca konten file itu, dan hitung ukurannya.

Akhirnya, ls -lhanya alat untuk mendaftarkan item secara interaktif. Jarang cocok untuk skrip. Saat Anda benar-benar perlu membaca data, gunakan wc -csaja.

Harap dicatat, bahwa untuk skrip dan menilai ukuran file, lsbukan kandidat terbaik. Sebenarnya, ini adalah salah satu praktik umum untuk menghindari penguraian lsoutput . Silakan gunakan du -b untuk mengetahui ukuran file.

Sergiy Kolodyazhnyy
sumber
1
Klarifikasi kecil - file virtual (di /sys/, /proc/, dll) dapat memberikan statinformasi, jika lagi memilih pelaksana. Sebagian besar waktu, tidak ada alasan kuat untuk itu, jadi itu dihilangkan. Contohnya termasuk /proc/kcoreyang dilaporkan sebagai ukuran memori kernel addressable (biasanya jauh lebih banyak daripada memori fisik yang tersedia).
Toby Speight
11

ls -l akan mengembalikan ukuran file yang dilaporkan oleh sistem file.

wc -cakan berusaha membaca file untuk menentukan ukuran 'aktual'. Dari pengamatan saya tampaknya pertama mencoba mencari sampai akhir, dan jika ini tidak berhasil, itu akan membacakan seluruh file, menghitung ukuran saat berjalan.

Ini adalah deskripsi sederhana tentang apa yang dilakukan kedua alat, tetapi mengarah ke sejumlah implikasi untuk hasil:

lsakan memberikan output yang salah untuk sistem file tertentu. Sebagai contoh, sistem file tervirtualisasi seperti /procakan melaporkan ukuran nol untuk banyak file, karena "file" ini tidak disimpan secara fisik di mana pun; mereka dihasilkan sesuai kebutuhan oleh perangkat lunak.

wctidak akan berfungsi sama sekali untuk file tanpa izin baca, sedangkan lshanya memerlukan izin untuk mendaftar direktori (bandingkan ls -l /etc/shadowdengan wc -c /etc/shadow).

Seperti disebutkan dalam jawaban lain, perilaku tautan simbolik juga berbeda. Karena wcmencoba membacanya, akhirnya membaca file yang ditunjuk symlink, sedangkan karena lshanya menanyakan filesystem, ia akan melaporkan ukuran yang digunakan untuk menyimpan tautan simbolik itu sendiri.

Saya yakin ada perbedaan lain yang belum saya pikirkan, tetapi saya pikir saya akan memberikan penjelasan yang jelas dan sederhana tentang alasan dasar di balik perbedaan ini.

Muzer
sumber
+1 untuk menyebutkan izin baca dan seek(). Ini tampaknya menjadi masalah, setelah dijalankan strace wc -lpada beberapa file besar.
Sergiy Kolodyazhnyy
+1 untuk menambahkan lebih banyak detail daripada jawaban saya!
Cyclic3
6

Untuk file normal, ls dan stat panggilan wc. Namun, untuk file / proc atau / sys, ls mengembalikan 0, tetapi wc mengembalikan nomor yang berbeda:

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

Ini mungkin beberapa cara untuk mencari tahu apakah ada file khusus.

Siklik3
sumber
2
wc -cbagi saya setidaknya panggilan fstat, tetapi tampaknya untuk tujuan lain. Itu menemukan panjang file dengan lseeking sampai akhir. Jika ini mengembalikan kesalahan, itu readadalah seluruh file.
Muzer