Obviamente, a maneira padrão de testar se um arquivo está vazio é com test -s FILE
, mas um de nossos clientes recebeu um script contendo testes como este:
RETVAL=`ls -s ./log/cr_trig.log | awk '{print $1}'`
if test $RETVAL -ne 0
then
echo "Badness: Log not empty"
exit 25
fi
com alegações do fornecedor de que ele trabalha nos dois ambientes em que o testaram. Desnecessário dizer que ele falhou muito nos dois locais em que o testei.
Então, fiquei curioso. Quando é que ls -s
imprime 0
para arquivos vazios?
Estas são as minhas descobertas até agora:
- GFS no Linux: 4
- ext4 no Linux: 0
- ZFS no Solaris: 1
- UFS no Solaris: 0
- jfs no AIX: 0
- VxFS no HP-UX: 0
- HFS no HP-UX: 0
- HFS no Mac OS X: 0
Ainda não examinei os sistemas de arquivos em rede.
Pergunta: Como posso explicar elegantemente aos outros que seus scripts estão errados ?
Na minha opinião, a versão "correta" seria:
if test ! -s ./log/cr_trig.log
then
echo "Badness: Log not empty"
exit 25
fi
filesystems
shell-script
ls
compatibility
MattBianco
fonte
fonte
Respostas:
Achado muito interessante. Embora eu nunca tenha usado
ls -s
para verificar se um arquivo está vazio ou não, eu teria assumido que ele também informa0
sobre arquivos vazios.Para sua pergunta: como Mat já comentou, mostre a eles seus resultados de teste. Para explicar os resultados, indique que
ls -s
relata a quantidade de blocos alocados no sistema de arquivos, não o tamanho real em bytes. Obviamente, algumas implementações de sistema de arquivos alocam blocos, mesmo que não precisem armazenar dados, em vez de armazenar apenas um ponteiro NULL no inode.A explicação para isso pode estar relacionada ao desempenho. Criar arquivos vazios que permanecerão vazios é uma exceção ao processamento normal (o uso mais comum que eu vi seria a criação de arquivos de status em que a existência de um arquivo representa um determinado estado do software).
Porém, normalmente, um arquivo criado receberá alguns dados em breve; portanto, os designers de um determinado FS podem ter assumido que vale a pena alocar imediatamente um bloco de dados na criação do arquivo; portanto, quando os primeiros dados chegarem, essa tarefa já estará concluída.
A segunda razão pode ser que um arquivo continha dados no passado que foram apagados. Em vez de liberar o último bloco de dados, pode valer a pena manter esse bloco de dados para reutilização no mesmo arquivo.
EDITAR:
Mais um motivo: os sistemas de arquivos nos quais você encontrou valores> 0 são o ZFS , a implementação RAID + LVM + FS e o GFS , um sistema de arquivos em cluster. Ambos podem ter que armazenar metadados para manter a integridade do arquivo que não é armazenada nos inodes. Pode ser que isso
ls -s
conte nos blocos de dados alocados para esses metadados.fonte
Ao contrário da maioria dos outros sistemas de arquivos (se não todos), o ZFS não pré-aloca uma matriz estática de inodes. A criação de um arquivo vazio no ZFS utilizará um novo bloco de dados, o que é relatado por
ls -s
.Suspeito que o GFS precise armazenar dados de sincronização / bloqueio levando a outro resultado diferente de zero.
fonte
ls -s
relata o número de blocos alocados para o arquivo, sem incluir o que estiver armazenado diretamente na entrada do diretório.Na maioria dos casos, o número de blocos é o número de bytes dividido pelo tamanho do bloco em bytes, arredondado para cima.
O número de blocos pode ser menor que o de um arquivo esparso . Por exemplo, na maioria dos sistemas de arquivos, isso criará um arquivo de 8192 bytes, abrangendo 0 blocos:
Por outro lado, o número de blocos pode ser maior se o sistema de arquivos pré-alocar blocos para arquivos ou usar blocos para armazenar metadados. Não estou surpreso que o Zfs tenha uma correspondência não óbvia entre o tamanho do arquivo e o número de blocos, dado o grande número de recursos que ele oferece e sua orientação para grandes sistemas de arquivos; Não conheço os detalhes, mas o número de blocos depende não apenas do tamanho dos arquivos, mas também de seu histórico (você pode ter mais de um bloco em um arquivo vazio se for o resultado de truncar um arquivo maior).
Para explicar por que
ls -s
está errado: ele não conta o tamanho do arquivo, mas uma quantidade dependente do sistema de arquivos. É uma maneira muito indireta de determinar se um arquivo está vazio em primeiro lugar, exigindo uma ferramenta externa (ls
) e algumas análises; em vez disso, eles devem usartest -s
, o que não requer análise, e executa exatamente o que é solicitado. Se eles acham quels -s
é uma boa maneira de testar se um arquivo está vazio, o ônus deve estar neles para justificar que funciona.fonte