จำนวนไบต์ของ“ ls -l <สุ่มไฟล์>” เทียบกับ“ wc -c <สุ่มไฟล์>”


25

มีสถานการณ์ที่เป็นไปได้เมื่อใด

ls -l file.txt

แสดงจำนวนไบต์ไม่เท่ากัน

wc -c file.txt

ในสคริปต์หนึ่งฉันพบว่าการเปรียบเทียบค่าทั้งสองนั้น อะไรคือเหตุผลของสิ่งนั้น? เป็นไปได้ไหมที่จะมีจำนวนไบต์ต่างกันในไฟล์เดียวกัน


2
คุณช่วยอธิบายบริบทที่พบสคริปต์นี้ได้ไหม
Kusalananda

ดูเพิ่มเติมunix.stackexchange.com/a/321502/22565
Stéphane Chazelas

คำตอบ:


13

ใช่มีกรณีดังกล่าว

ในกรณีของการsymlinksในระบบ Linux กับ GNU lsที่ls -lจะทำให้ขนาดของการเชื่อมโยงในขณะที่wc -cจะแก้ไขไฟล์จริงและอ่านจำนวนไบต์ที่มี ด้านล่างคุณจะเห็นว่าls -lรายงาน 29 ไบต์ในขณะที่wcรายงาน 172 ไบต์ในไฟล์จริง

$ 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

ในกรณีของระบบไฟล์เสมือน , เช่น/proc หรือ/sysไฟล์จำนวนมากจะมีการแสดงให้เห็นว่ามีขนาด ls -l0 ภายใต้/devระบบไฟล์เรามีไฟล์พิเศษที่หลากหลายเช่นอุปกรณ์ตัวละครและอุปกรณ์บล็อค - wc -cแฮงค์มันและls -lแสดงหมายเลขหลักและรองแทนขนาด

ไปป์ที่มีชื่อจะถูกรายงานเป็น0ไบต์โดยls -cแต่wc -cจะอ่านเนื้อหาของไปป์ไลน์ดังนั้นในทางเทคนิคแล้วมันจะบอกคุณว่ามีข้อมูลอยู่ในไพพ์ที่มีชื่อเท่าไร:

$ 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 

สำหรับไฟล์ปกติขนาดควรเท่ากัน


จุดls -lและwc -cและวิธีการทำงานยังแตกต่างกัน wc -cจริง ๆ แล้วเปิดไฟล์สำหรับอ่าน (คุณจะเห็นว่าถ้าคุณเรียกใช้strace wc -c /etc/passwdตัวอย่าง) ls -lทำการstat()โทรเท่านั้น นอกจากนี้ยังอธิบายว่าทำไม/proc ls -lขนาดที่แสดงถึง 0 - คุณไม่สามารถสร้างไฟล์เหล่านั้นได้เนื่องจากไฟล์เหล่านั้นไม่ใช่ "ของจริง" หรือเก็บไว้ในฮาร์ดไดรฟ์ / ssd wc -cแทนอ่านเนื้อหาของไฟล์แทนและคำนวณขนาดไฟล์แทน

ในที่สุดls -lเป็นเพียงเครื่องมือสำหรับการแสดงรายการแบบโต้ตอบ มันไม่ค่อยเหมาะสำหรับการเขียนสคริปต์ เมื่อคุณต้องการอ่านข้อมูลให้ใช้wc -cแทน

โปรดทราบว่าสำหรับการเขียนสคริปต์และการประเมินขนาดของไฟล์lsนั้นไม่ใช่ตัวเลือกที่ดีที่สุด ในความเป็นจริงมันเป็นหนึ่งในวิธีปฏิบัติร่วมกันกับหลีกเลี่ยงการแยกlsเอาท์พุท กรุณาใช้du -b สำหรับการหาขนาดของไฟล์


1
คำอธิบายเล็ก ๆ - ไฟล์เสมือน (ใน/sys/, /proc/ฯลฯ ) อาจให้statข้อมูลหากผู้ดำเนินการเลือก ส่วนใหญ่ไม่มีเหตุผลที่น่าสนใจดังนั้นจึงถูกละไว้ ตัวอย่างรวมถึง/proc/kcoreรายงานขนาดของหน่วยความจำเคอร์เนลที่กำหนดแอดเดรสได้ (โดยปกติจะมากกว่าหน่วยความจำฟิสิคัลที่มีอยู่)
Toby Speight

11

ls -l จะคืนขนาดของไฟล์ที่รายงานโดยระบบไฟล์

wc -cจะพยายามอ่านไฟล์เพื่อกำหนดขนาด 'จริง' จากการสังเกตของฉันดูเหมือนจะพยายามค้นหาจุดจบก่อนและถ้าไม่ได้ผลมันจะอ่านไฟล์ทั้งหมดและนับขนาดตามที่ไป

นี่เป็นคำอธิบายง่ายๆเกี่ยวกับสิ่งที่เครื่องมือทั้งสองทำ แต่นำไปสู่ความเกี่ยวข้องหลายประการสำหรับผลลัพธ์:

lsจะให้ผลลัพธ์ที่ไม่ถูกต้องสำหรับระบบไฟล์บางระบบ ตัวอย่างเช่นระบบไฟล์เสมือนจริง/procจะรายงานขนาดเป็นศูนย์สำหรับไฟล์จำนวนมากเนื่องจาก "ไฟล์" เหล่านี้ไม่ได้ถูกจัดเก็บในที่ใด ๆ มันถูกสร้างขึ้นตามความต้องการของซอฟต์แวร์

wcจะไม่ทำงานเลยสำหรับไฟล์ที่ไม่มีสิทธิ์อ่านในขณะที่lsต้องการเฉพาะสิทธิ์ในการแสดงรายการไดเรกทอรี (เปรียบเทียบls -l /etc/shadowกับwc -c /etc/shadow )

ดังที่กล่าวไว้ในคำตอบอื่น ๆ พฤติกรรมของลิงก์สัญลักษณ์ก็แตกต่างกันเช่นกัน เพราะwcพยายามที่จะอ่านมันจบลงด้วยการอ่านไฟล์ที่จุด symlink ในขณะที่เพราะlsเพียงแค่สอบถามระบบไฟล์มันจะรายงานขนาดที่ใช้ในการจัดเก็บลิงก์สัญลักษณ์เอง

ฉันแน่ใจว่ามีความแตกต่างอื่น ๆ ที่ฉันยังไม่ได้คิด แต่ฉันคิดว่าฉันจะให้คำอธิบายที่ชัดเจนและเรียบง่ายเกี่ยวกับเหตุผลพื้นฐานที่อยู่เบื้องหลังความแตกต่างเหล่านี้


+1 seek()สำหรับการกล่าวขวัญสิทธิ์อ่านและ นี่เป็นกรณีหลังจากเรียกใช้strace wc -lไฟล์ขนาดใหญ่คู่
Sergiy Kolodyazhnyy

+1 สำหรับการเพิ่มรายละเอียดมากกว่าคำตอบของฉัน!
Cyclic3

6

สำหรับไฟล์ปกติ ls และ wc call stat อย่างไรก็ตามสำหรับไฟล์ของ / proc หรือ / sys ls จะคืนค่า 0 แต่ wc จะคืนค่าตัวเลขอื่น:

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

นี่อาจเป็นวิธีในการค้นหาว่าบางสิ่งบางอย่างเป็นไฟล์พิเศษ


2
wc -cอย่างน้อยฉันก็โทรfstatแต่ดูเหมือนว่าเพื่อวัตถุประสงค์อื่น มันจะค้นหาความยาวของไฟล์โดยเริ่มlseekต้นจนจบ ในกรณีที่ส่งคืนข้อผิดพลาดมันreadเป็นไฟล์ทั้งหมด
Muzer
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.