Como o redirecionamento de entrada funciona?

5

Sim, eu já tentei procurar em outro lugar, mas os exemplos que devem ilustrar o redirecionamento de entrada, como aqui por exemplo, sempre tem uma advertência confusa. No exemplo do site postado, eles dizem:

  # echo 'hello world' >output
  # cat <output
  

A primeira linha escreve "hello world" para o arquivo "output", o segundo   lê de volta e escreve na saída padrão (normalmente o   terminal).

No entanto, cat output faria exatamente a mesma coisa, sem necessidade de < aqui. Então, qual é a diferença?

    
por AlphaOmega 15.02.2017 / 22:56

2 respostas

4

O redirecionamento de entrada (como em cat < file ) significa que o shell está abrindo o arquivo de entrada e gravando seu conteúdo na entrada padrão de outro processo. Passar o arquivo como um argumento (como acontece ao executar cat file ) significa que o programa que você está usando (por exemplo, cat ) precisa abrir o próprio arquivo e ler o conteúdo.

Basicamente, command file passa um arquivo para command enquanto command < file passa o conteúdo de um arquivo para command . Sim, em casos como cat file vs cat < file não há diferença facilmente percebida no resultado, mas os dois funcionam de maneiras diferentes.

Para entender a diferença, pense em uma criança pequena e um adulto. Ambos podem beber água. No entanto, o adulto pode abrir a torneira e encher um copo (abrir o arquivo e ler seu conteúdo) enquanto a criança precisa que a água seja fornecida diretamente (não é possível abrir o arquivo e só pode processar seu conteúdo). / p>

Alguns programas, como o cat , são capazes de pegar um nome do arquivo como entrada e então abrir o arquivo e fazer o que quiserem nele. É por isso que cat file funciona. Outros programas, no entanto, não têm nenhum conhecimento sobre quais arquivos são ou como usá-los. Tudo o que eles sabem é fluxos de entrada (como o conteúdo do arquivo). Por exemplo, tr :

$ cat file
foo
$ cat file | tr 'o' 'b'  ## tr can read a stream
fbb
$ tr 'o' 'b' file  ## tr can't deal with files
tr: extra operand ‘file’
Try 'tr --help' for more information.
$ tr 'o' 'b' < file ## input redirection!
fbb

Outro exemplo é ls , que pode lidar com os arquivos muito bem, mas ignora os fluxos de entrada:

$ ls
file1  file2
$ ls file1   ## lists only file1: ls takes file names as arguments
file1
$ ls < file1 ## ls ignores its standard input, this is the same as ls alone
file1 file2

Outros programas não podem lidar com fluxos e, em vez disso, exigem arquivos:

$ rm < file ## fails, rm needs a file 
rm: missing operand
Try 'rm --help' for more information.
$ rm file ## works, file is deleted

Alguns programas podem lidar com arquivos de abertura e leitura de fluxos de entrada, mas comportam-se de maneiras diferentes em cada um deles. Por exemplo, wc que, quando recebe um arquivo para abrir, imprime o nome do arquivo, bem como o número de linhas, palavras e caracteres:

$ wc file
1 1 4 file

Mas, se dermos apenas um fluxo, não há como saber que isso vem de um arquivo específico, portanto, nenhum nome de arquivo é impresso:

$ wc < file
1 1 4

O comando md5sum se comporta de maneira semelhante:

$ md5sum file
17fd54512c91e3cd0f70fbaaa9a94d0d  file
$ md5sum < file
17fd54512c91e3cd0f70fbaaa9a94d0d  - 

Note que no primeiro caso o nome do arquivo file é mostrado enquanto, no segundo, "nome do arquivo" é - : entrada padrão.

Agora, se você quiser mais detalhes, você pode usar strace para ver exatamente o que está acontecendo:

strace -e trace=open,close,read,write wc file 2>strace1.txt

e

strace -e trace=open,close,read,write wc < file 2>strace2.txt

Eles terão todos os detalhes de todas as operações open() , close() e read() executadas pelo processo. O que você quer ver é que strace1.txt (quando o arquivo foi passado como argumento e não com redirecionamento de entrada) contém estas linhas:

open("file", O_RDONLY)                  = 3
read(3, "foo\n", 16384)                 = 4

Isso significa que o arquivo file foi aberto e anexado ao descritor de arquivo 3 . Em seguida, a string foo\n foi lida de 3 . A parte equivalente da saída strace ao usar o redirecionamento de entrada é:

read(0, "foo\n", 16384)                 = 4

Não há uma chamada open() correspondente, em vez disso, a string foo\n está sendo lida de 0 , a entrada padrão 1 .

1 Por padrão, 0 é a entrada padrão, 1 é a saída padrão e 2 é o erro padrão. Isto, por sinal, é porque file foi aberto como 3 , que foi o próximo disponível.

    
por terdon 16.02.2017 / 00:53
1

Basicamente as diferenças são:

  1. cat output.txt : lê o conteúdo do arquivo output.txt para saída padrão diretamente

  2. cat < output.txt : a saída (ou conteúdo) de output.txt através do símbolo de entrada padrão de redirecionamento ( < ) é lida pelo cat comando. Portanto output.txt é usada uma entrada para o comando < .

A saída para os dois métodos será a mesma, mas um caminho extra será usado no segundo método como resultado do símbolo de entrada padrão < de redirecionamento.

    
por George Udosen 15.02.2017 / 23:32