A cauda lê o arquivo inteiro?

106

Se eu quiser tail um arquivo de texto de 25 GB, o comando tail lerá todo o arquivo?

Como um arquivo pode estar espalhado em um disco, imagino que seja necessário, mas não entendo bem esses recursos internos.

    
por The Unfun Cat 28.11.2013 / 10:48

4 respostas

113

Não, tail não leu todo o arquivo, ele busca até o final e depois lê blocos para trás até que o número esperado de linhas seja atingido, então exibe as linhas na direção correta até o final do arquivo e, possivelmente, fica monitorando o arquivo se a opção -f for usada.

Observe, entretanto, que tail não tem escolha a não ser ler os dados completos, desde que seja fornecida uma entrada não pesquisável, por exemplo, ao ler de um pipe.

De forma semelhante, quando solicitado a procurar linhas iniciando no início do arquivo, usando a opção tail -n +linenumber ou tail +linenumber não padrão quando suportado, tail obviamente lê o arquivo inteiro (a menos que seja interrompido). / p>     

por 28.11.2013 / 10:52
65

Você poderia ter visto como tail funciona sozinho. Como você pode para um dos meus arquivos read é feito três vezes e no total aproximadamente 10K bytes são lidos:

strace 2>&1  tail ./huge-file >/dev/null  | grep -e "read" -e "lseek" -e "open" -e "close"
open("./huge-file", O_RDONLY)           = 3
lseek(3, 0, SEEK_CUR)                   = 0
lseek(3, 0, SEEK_END)                   = 80552644
lseek(3, 80551936, SEEK_SET)            = 80551936
read(3, ""..., 708) = 708
lseek(3, 80543744, SEEK_SET)            = 80543744
read(3, ""..., 8192) = 8192
read(3, ""..., 708) = 708
close(3)                                = 0
    
por 28.11.2013 / 11:03
25

Since a file might be scattered on a disk I imagine it has to [read the file sequentially], but I do not understand such internals well.

Como você sabe agora, tail procura apenas o final do arquivo (com a chamada do sistema lseek ) e funciona de trás para frente. Mas na observação citada acima, você está se perguntando "como a cauda sabe onde no disco encontrar o final do arquivo?"

A resposta é simples: a cauda não sabe. Os processos no nível do usuário vêem os arquivos como fluxos contínuos, portanto, tudo que o tail pode saber é o deslocamento desde o início do arquivo. Mas no sistema de arquivos, o "inode" do arquivo (entrada de diretório) é associado a uma lista de números que denota a localização física dos blocos de dados do arquivo. Quando você lê o arquivo, o kernel / o driver de dispositivo descobre de qual parte você precisa, calcula sua localização no disco e procura por você.

Esse é o tipo de coisa para a qual temos sistemas operacionais: assim, você não precisa se preocupar com onde os blocos do seu arquivo estão espalhados.

    
por 28.11.2013 / 17:10
1

Se head ou tail aparecer para ler o arquivo inteiro, uma razão provável é que o arquivo contém poucos ou nenhum caractere de nova linha . Eu tropecei nisso alguns meses atrás com um blob JSON muito grande (gigabytes) que tinha sido serializado sem nenhum espaço em branco, nem mesmo em strings.

Se você tem o GNU head / tail você pode usar -c N para imprimir o primeiro / último N bytes ao invés de linhas , mas infelizmente este não é um recurso POSIX .

    
por 05.07.2016 / 20:12

Tags