Por que o sinal de menor que não funciona como um substituto para o cat in bash?

15

Eu ouvi sobre "uso inútil de gato" e encontrei algumas sugestões, mas o seguinte não produz nada na minha concha bash.

< filename

Usar cat funciona como esperado.

cat filename

Estou usando o Fedora Core 18 e o GNU bash, versão 4.2.45 (1).

EDIT: usá-lo na frente de um cano não funciona.

< filename | grep pattern

Considerando que o uso de cat funciona como esperado.

cat filename | grep pattern

EDIT2: Para esclarecer, sei que posso usar isso

grep pattern < filename

mas eu li aqui link que também posso usar na frente do comando. Não funciona na frente do comando embora.

    
por bug 20.12.2013 / 15:07

3 respostas

19

O símbolo less than e ( < ) está abrindo o arquivo e anexando-o ao manipulador de dispositivo de entrada padrão de algum aplicativo / programa. Mas você não deu ao shell qualquer aplicativo para anexar a entrada.

Exemplo

Esses dois exemplos fazem essencialmente a mesma coisa, mas obtêm sua contribuição em duas maneiras ligeiramente diferentes.

abre o arquivo

$ cat blah.txt 
hi

abre STDIN

$ cat < blah.txt 
hi

Espreitando por trás da cortina

Você pode usar strace para ver o que está acontecendo.

Quando lemos de um arquivo

open("blah.txt", O_RDONLY)              = 3
fstat(3, {st_mode=S_IFREG|0664, st_size=3, ...}) = 0
fadvise64(3, 0, 0, POSIX_FADV_SEQUENTIAL) = 0
read(3, "hi\n", 65536)                  = 3
write(1, "hi\n", 3hi
)                     = 3
read(3, "", 65536)                      = 0
close(3)                                = 0
close(1)                                = 0

Quando lemos de STDIN (identificado como 0)

read(0, "hi\n", 65536)                  = 3
write(1, "hi\n", 3hi
)                     = 3
read(0, "", 65536)                      = 0
close(0)                                = 0
close(1)                                = 0

No primeiro exemplo, podemos ver que cat abriu o arquivo e leu a partir dele, blah.txt . Na segunda podemos ver que cat lê o conteúdo do arquivo blah.txt via descritor de arquivo STDIN, identificado como descritor número 0.

read(0, "hi\n", 65536)                  = 3
    
por 20.12.2013 / 15:10
13

O uso inútil e clássico de cat é quando você o usa para dar entrada a programas que são perfeitamente capazes de abrir arquivos diretamente. Por exemplo:

Ruim

cat file | grep foo
cat file | while read line; do echo "$line"; done
cat file | sed 's/a/b/'
cat file | awk '{print $1}'

Bom

grep foo file
while read line; do echo "$line"; done < file 
sed 's/a/b/' file
awk '{print $1}' file

Também é bom (o <file pode estar em ambos os lados do comando)

<file grep foo
 sed 's/a/b/' < file
<file awk '{print $1}' 
    
por 20.12.2013 / 15:19
10

O UUOC está em:

cat somefile | some-cmd

ou

cat < somefile | some-cmd

Lá, some-cmd está lendo o conteúdo de somefile de um canal alimentado por cat , que o lê de somefile .

some-cmd pode ler diretamente de somefile (depois que o shell abriu para stdin), não há necessidade de cat :

some-cmd < somefile

ou

< somefile some-cmd

(os redirecionamentos podem aparecer em qualquer lugar em uma linha de comando simples).

    
por 20.12.2013 / 15:18