Por que ele se dirige; cauda em um arquivo grande, por vezes, demorar muito tempo e às vezes não?

2

Estou escrevendo um script que lê as 10 primeiras linhas e as últimas 10 linhas de um arquivo .txt. Ele procura por iniciado (head) e completed (tail) e compara o número de ocorrências usando grep. Os arquivos são muito grandes e é por isso que optei por apenas ler a cabeça e cauda dos arquivos em vez de todo o texto. No entanto, quando executo o script, os arquivos grandes demoram muito tempo para "terminar" (que consiste em ler as primeiras 10 linhas e as últimas 10 linhas e a comparação, uma tarefa que deve levar apenas um ou dois momentos).

Enquanto assistia ao texto de saída do script, notei esse problema. Então eu decidi ver se levaria uma quantidade de tempo similar quando eu simplesmente executasse o comando head / tail (mais grep, como simular o que está sendo executado no script) direto da linha de comando. Surpreendentemente, os comandos executados quase instantaneamente. Eu pensei que isso era estranho e eu corri o roteiro novamente. Desta vez, o script iria gritar através do arquivo que estava preso antes até chegar ao próximo arquivo "grande" que eu ainda não tinha executado o comando head / tail / grep.

Isso me fez pensar, o bash armazena os resultados de um comando semelhante ao cache? Além disso, o que poderia estar causando esses comandos:

 head -n 10 /file/path/myfile.txt | grep -w -c 'lead word'
 tail -n 10 /file/path/myfile.txt | grep -w -c 'end word'

demorará tanto para ser executado?

edit: A razão pela qual eu acredito que é a cabeça / cauda linhas acima que são a fonte do problema é porque existem linhas de eco que devem imprimir após a conclusão da cabeça / cauda individualmente. Verifiquei o tamanho da linha dos arquivos e eles não são muito mais longos do que aqueles que estão terminando em alguns instantes.

Alguém poderia me dar uma explicação mais detalhada de como a cabeça / cauda funciona em um nível mais técnico? Eu tenho uma compreensão muito básica de "o primeiro / último x linhas" de um arquivo.

    
por Racehorse35 17.08.2017 / 16:57

1 resposta

1

Não, o bash não armazena em cache a saída de comandos, uma vez que a saída pode mudar de execução para execução; O bash não tem uma maneira infalível de rastrear se o arquivo foi modificado por outro processo, o que seria crítico, de modo que bash pudesse dizer se seu resultado em cache ainda era válido ou não.

No entanto, há outras coisas em jogo aqui. Quando você usa um shell (como bash ), você está interagindo simultaneamente com várias partes do sistema. Por exemplo:

  • O próprio shell
  • GNU Readline, que é uma interface de edição de linha usada por vários shells e outras ferramentas
  • A implementação libc , que pode causar um comportamento confuso em quase todos os programas de tempos em tempos.
  • O próprio terminal, que pode ter um comportamento peculiar, e pode realmente responder aos comandos próprios . (Por exemplo, o Backspack e Delete podem estar indisponíveis ou podem ser trocados)
  • A janela da GUI na qual o terminal existe dentro (se aplicável). Por exemplo. ele pode ter um IME que permite digitar caracteres Unicode no terminal com uma seqüência de teclas especial (como Ctrl + Deslocamento + u seguido por um número.)
  • O kernel, incluindo todos os seus módulos e drivers
  • O hardware em si, que, é claro, pode superaquecer, causar curto-circuito, perda de energia, etc.

Nesse caso, eu diria que o maior contribuidor não é bash em si, mas o mecanismo de armazenamento em cache no nível do sistema de arquivos é implementado no kernel. Uma vez que você tenha lido um arquivo uma vez, uma grande parte dele pode acabar no cache do sistema de arquivos, que é um pedaço de memória reservada para essa finalidade.

Ao executar operações no arquivo uma segunda vez, o shell não aciona uma leitura de hardware físico novamente, mas recupera o conteúdo do arquivo do cache. Quase qualquer operação que você (re) executar no bash será extremamente rápida em comparação com uma leitura de disco. É por isso que você não percebe que o bash está realmente executando novamente os comandos, porque a leitura do disco lento está faltando.

    
por 17.08.2017 / 17:34