Existe diferença entre ler, head -1 e sed 1q?

7

Os seguintes comandos parecem ser aproximadamente equivalentes:

read varname
varname=$(head -1)
varname=$(sed 1q)

Uma diferença é que read é um shell embutido, enquanto head e sed não são.

Além disso, existe alguma diferença de comportamento entre os três?

Minha motivação é entender melhor as nuances do shell e dos principais utilitários, como head,sed . Por exemplo, se usar head for um substituto fácil para read , por que o read existe como um arquivo interno?

    
por Tyler 26.09.2014 / 20:00

4 respostas

5

Nem a eficiência nem a integridade são a maior diferença. Todos eles retornarão uma saída diferente para determinada entrada.

  • head -n1 fornecerá uma nova linha à direita apenas se a entrada tiver uma.

  • sed 1q sempre fornecerá uma nova linha, mas preservará a entrada.

  • read nunca fornecerá uma nova linha e interpretará sequências de contrabarra.

Além disso, read tem opções adicionais, como divisão, tempos limite e histórico de entrada, alguns dos quais são padrão e outros variam entre os shells.

    
por 27.09.2014 / 20:27
5

Por um lado, você pode analisar texto com leitura, não apenas uma linha inteira

echo "foo:bar:baz" | {
  IFS=: read one two three
  echo $two
}
    
por 26.09.2014 / 20:05
4

As builtins estão presentes como uma maneira de fazer com que o sistema chame mais rapidamente. Então, acredito que o comando read esteja presente como um builtin para ser mais eficiente.

Citações de aqui ,

These builtin commands are part of the shell, and are implemented as part of the shell's source code. The shell recognizes that the command that it was asked to execute was one of its builtins, and it performs that action on its own, without calling out to a separate executable. Different shells have different builtins, though there will be a whole lot of overlap in the basic set.

Agora, gostaria que isso fosse feito por você mesmo, para que você possa entender por que read está presente como um shell interno.

Normalmente, você não pode fazer strace em builtins de shell. No entanto, há uma solução alternativa para isso também. Isso é explicado de maneira muito precisa neste responder .

  1. No primeiro shell, execute o comando como stty -echo .
  2. Abra outro shell e execute o comando como cat | strace bash > /dev/null .
  3. Agora, o shell estaria aguardando o usuário digitar os comandos e lá, quando o usuário digita os comandos, você pode ver o que acontece no nível do sistema também.
  4. Quando você dá os 3 comandos acima, você pode ver que a leitura menos chamadas do sistema do que os 2 comandos restantes. Eu não estou colando a saída de strace , pois é muito grande.
por 26.09.2014 / 20:17
0

Você pode usar varname somente leitura dentro de um script de shell, mas você pode usar outros dois sem escrever o script de shell.

Por exemplo:

Você pode usar varname=$(head -1) e varname=$(sed 1q) simplesmente como um comando no terminal, mas você precisa fornecer seu argumento também, ou seja, quais arquivos da linha superior você está referindo, por exemplo, varnam=$(head -1 file1) .

    
por 26.09.2014 / 20:54