Contagem de bytes de "ls -l <arquivo aleatório>" versus a de "wc -c <arquivo aleatório>"

25

Existe alguma situação possível quando

ls -l file.txt

está mostrando não o mesmo número de bytes que

wc -c file.txt

Em um script, encontrei a comparação desses dois valores. Qual poderia ser a razão disso? É possível ter contagens de bytes diferentes do mesmo arquivo?

Rokas.ma
fonte
2
Você poderia dar algum contexto a esse script que você encontrou?
Kusalananda
Veja também unix.stackexchange.com/a/321502/22565
Stéphane Chazelas

Respostas:

13

Sim, existem casos assim.

No caso de links simbólicos no sistema Linux com GNU ls, ele ls -lexibirá o tamanho do link, enquanto wc -cresolverá o arquivo real e lerá o número de bytes lá. Abaixo, você pode ver que ls -lreporta 29 bytes, enquanto wcreporta 172 bytes no arquivo real.

$ 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

No caso de sistemas de arquivos virtuais , como/proc ou /sys, muitos arquivos serão mostrados com tamanho 0 ls -l. No /devsistema de arquivos, temos uma variedade de arquivos especiais, como dispositivos de caracteres e dispositivos de bloco - wc -ctrava neles e ls -lmostra números maiores e menores em vez de tamanho.

Os pipes nomeados serão relatados como 0bytes por ls -c, mas wc -crealmente lerão o conteúdo do pipe, portanto, tecnicamente, ele informará quantos dados há no pipe nomeado:

$ 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 

Para arquivos regulares, o tamanho deve ser igual.


O ponto de ls -le wc -c, e como eles funcionam também difere. wc -cabre realmente o arquivo para leitura (você pode ver isso se executar, strace wc -c /etc/passwdpor exemplo). ls -lsó realiza stat()chamadas naqueles. Isso também explica o motivo pelo qual /proc ls -lmostra o tamanho 0 - você não pode declarar esses arquivos porque eles não são "reais" ou realmente armazenados no disco rígido / ssd. wc -cem vez disso, lê o conteúdo desse arquivo e calcula seu tamanho.

Por fim, ls -lé apenas uma ferramenta para listar itens interativamente. Raramente é um bom ajuste para scripts. Quando você realmente precisar ler os dados, use wc -c.

Observe que, para criar scripts e avaliar o tamanho de um arquivo, lsnão é o melhor candidato. De fato, é uma das práticas comuns evitar a análise de lssaída . Por favor, use du -b para descobrir o tamanho de um arquivo.

Sergiy Kolodyazhnyy
fonte
11
Um pequeno esclarecimento - arquivos virtuais (em /sys/, /proc/etc) podem fornecer statinformações, se o implementador escolher. Na maioria das vezes, não há um motivo convincente para isso, portanto é omitido. Exemplos incluem o /proc/kcoreque é relatado como o tamanho da memória endereçável do kernel (geralmente muito mais do que a memória física disponível).
precisa saber é o seguinte
11

ls -l retornará o tamanho do arquivo relatado pelo sistema de arquivos.

wc -ctentará ler o arquivo para determinar o tamanho 'real'. Pelas minhas observações, parece tentar primeiro procurar o final e, se isso não funcionar, ele lerá o arquivo inteiro, contando o tamanho conforme for.

Essa é uma descrição simples do que as duas ferramentas fazem, mas leva a várias implicações para os resultados:

lsdará uma saída incorreta para certos sistemas de arquivos. Por exemplo, sistemas de arquivos virtualizados como /procreportarão um tamanho zero para muitos arquivos, porque esses "arquivos" não são fisicamente armazenados em nenhum lugar; eles são gerados conforme exigido pelo software.

wcnão funcionará para arquivos sem permissões de leitura, enquanto lsrequer apenas permissões para listar o diretório (compare ls -l /etc/shadowcom wc -c /etc/shadow).

Como mencionado em outras respostas, o comportamento dos links simbólicos também é diferente. Como wctenta lê-los, ele acaba lendo o arquivo para o qual o link simbólico aponta, enquanto, como lsapenas consulta o sistema de arquivos, informa o tamanho usado para armazenar o próprio link simbólico.

Tenho certeza de que existem outras diferenças em que ainda não pensei, mas pensei em dar uma explicação clara e simples sobre o motivo básico por trás dessas diferenças.

Muzer
fonte
+1 por mencionar permissões de leitura e seek(). Parece ser esse o caso, depois de executar strace wc -lalguns arquivos grandes.
Sergiy Kolodyazhnyy
+1 por adicionar muito mais detalhes do que a minha resposta!
precisa saber é o seguinte
6

Para um arquivo normal, ls e wc chamam stat. No entanto, para um arquivo de / proc ou / sys, ls retorna 0, mas wc retorna um número diferente:

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

Provavelmente, essa é uma maneira de descobrir se algo é um arquivo especial.

Cyclic3
fonte
2
wc -cpara mim, pelo menos, chama fstat, mas aparentemente para outros fins. Ele encontra o comprimento do arquivo lseekaté o final. Caso isso retorne um erro, readé o arquivo inteiro.
Muzer