Conteggio dei byte di "ls -l <file casuale>" rispetto a quello di "wc -c <file casuale>"


25

C'è qualche possibile situazione in cui

ls -l file.txt

non mostra lo stesso numero di byte di

wc -c file.txt

In uno script ho trovato il confronto di questi due valori. Quale potrebbe essere la ragione di ciò? È anche possibile avere conteggi di byte diversi dello stesso file?


2
Potresti dare un po 'di contesto a questo script che hai trovato?
Kusalananda

Risposte:


13

Sì, ci sono casi del genere.

In caso di collegamenti simbolici su un sistema Linux con GNU ls, ls -lverrà visualizzata la dimensione del collegamento, mentre wc -csi risolverà il file effettivo e si leggerà il numero di byte lì. Di seguito puoi vedere che ls -lriporta 29 byte, mentre wcriporta 172 byte nel file effettivo.

$ 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

Nel caso di filesystem virtuali , come/proc o /sys, molti file mostreranno la dimensione 0 ls -l. Nel /devfilesystem abbiamo una varietà di file speciali, come dispositivi a caratteri e dispositivi a blocchi - si wc -cblocca su questi e ls -lmostra numeri maggiori e minori invece di dimensioni.

Le pipe nominate verranno riportate come 0byte da ls -c, ma wc -cin realtà leggeranno il contenuto della pipe, quindi tecnicamente ti dirà quanti dati sono nella pipe denominata:

$ 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 

Per un file normale, la dimensione dovrebbe essere uguale.


Anche il punto di ls -le wc -c, e come funzionano, differisce. wc -capre effettivamente il file per la lettura (puoi vederlo se, strace wc -c /etc/passwdad esempio, lo esegui ). ls -lesegue solo stat()chiamate su quelli. Questo spiega anche perché in /proc ls -lmostra 0 dimensioni - non è possibile stat quei file perché non sono "reali" o effettivamente memorizzati sul disco rigido / SSD. wc -cinvece, legge il contenuto di quel file e calcola la sua dimensione.

Infine, ls -lè solo uno strumento per elencare gli oggetti in modo interattivo. Raramente si adatta bene agli script. Quando devi effettivamente leggere i dati, usa wc -cinvece.

Si noti che per lo scripting e la valutazione delle dimensioni di un file lsnon è il candidato migliore. In effetti, è una delle pratiche comuni per evitare l'analisi lsdell'output . Si prega di utilizzare du -b per scoprire la dimensione di un file.


1
Una piccola precisazione - file virtuali (a /sys/, /proc/, ecc) può fornire statinformazioni, se le sceglie Implementer a. Il più delle volte, non c'è un motivo convincente per farlo, quindi viene omesso. Gli esempi includono /proc/kcorequale è riportato come dimensione della memoria del kernel indirizzabile (di solito molto più della memoria fisica disponibile).
Toby Speight,

11

ls -l restituirà la dimensione del file segnalato dal filesystem.

wc -ctenterà di leggere il file per determinare la dimensione "effettiva". Dalle mie osservazioni sembra provare prima a cercare fino alla fine, e se questo non funziona, leggerà l'intero file, contando le dimensioni mentre procede.

Questa è una semplice descrizione di ciò che fanno i due strumenti, ma porta a una serie di implicazioni per i risultati:

lsfornirà un output errato per alcuni filesystem. Ad esempio, i filesystem virtualizzati come /procsegnaleranno una dimensione pari a zero per molti file, poiché questi "file" non sono archiviati fisicamente da nessuna parte; sono generati come richiesto dal software.

wcnon funzionerà affatto per i file senza autorizzazioni di lettura, mentre lsrichiede solo autorizzazioni per elencare la directory (confronta ls -l /etc/shadowcon wc -c /etc/shadow).

Come menzionato in altre risposte, anche il comportamento dei collegamenti simbolici è diverso. Poiché wctenta di leggerli, finisce per leggere il file a cui punta lsil collegamento simbolico , mentre poiché esegue semplicemente una query sul filesystem, riporterà le dimensioni utilizzate per memorizzare il collegamento simbolico stesso.

Sono sicuro che ci sono altre differenze a cui non ho ancora pensato, ma ho pensato di dare una spiegazione chiara e semplice sul motivo alla base di queste differenze.


+1 per menzionare i permessi di lettura e seek(). Questo sembra essere il caso, dopo aver eseguito strace wc -lsu un paio di file di grandi dimensioni.
Sergiy Kolodyazhnyy,

+1 per l'aggiunta di molti più dettagli rispetto alla mia risposta!
Cyclic3,

6

Per un file normale, ls e wc chiamano stat. Tuttavia, per un file di / proc o / sys, ls restituisce 0, ma wc restituisce un numero diverso:

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

Questo è probabilmente un modo per scoprire se qualcosa è un file speciale.


2
wc -calmeno per me chiama fstat, ma apparentemente per altri scopi. Trova la lunghezza del file lseekfino alla fine. Nel caso in cui ciò restituisca un errore, è readl'intero file.
Muzer,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.