Diferença entre "gato" e "gato <"

Respostas:

106

No primeiro caso, catabre o arquivo e, no segundo caso, o shell abre o arquivo, passando-o como catentrada padrão.

Tecnicamente, eles podem ter efeitos diferentes. Por exemplo, seria possível ter uma implementação de shell que fosse mais (ou menos) privilegiada que o catprograma. Nesse cenário, um pode falhar ao abrir o arquivo, enquanto o outro pode.

Esse não é o cenário usual, mas mencionado para apontar que o shell e catnão é o mesmo programa.

Thomas Dickey
fonte
83
Sim, e por exemplo você pode fazer sudo cat myfile.txt. Mas sudo cat < myfile.txtnão funcionará se você não tiver privilégios para ler o arquivo.
Zuazo
2
Observe que ele ksh93foi catembutido (não ativado por padrão, a menos que você tenha /opt/ast/binno início $PATH).
Stéphane Chazelas 02/02
2
Alguns programas se comportam de maneira diferente, dependendo de obterem um argumento de nome de arquivo ou stdin. Por exemplo, wcimprimirá o nome do arquivo antes da contagem quando houver um argumento.
Barmar
21

Não há grande diferença visível no seu caso de teste. A mais óbvia seria a mensagem de erro recebida se não houver um arquivo nomeado myfile.txtno diretório atual ou se você não tiver permissão para lê-lo.

No primeiro caso, catirá reclamar e, no último caso, seu shell mostrará claramente qual processo está tentando abrir o arquivo, catno primeiro e o shell no último.

$ cat myfile.txt
cat: myfile.txt: No such file or directory
$ cat < myfile.txt
ksh93: myfile.txt: cannot open [No such file or directory]

Em um caso mais geral, uma grande diferença é que o uso de redirecionamentos não pode ser usado para imprimir o conteúdo de mais de um arquivo, que é, afinal, o objetivo original do comando cat(por exemplo, cat enate). Observe que, de qualquer forma, o shell tentará abrir todos os arquivos passados ​​como entrada redirecionada, mas apenas passará o último para catmenos que você use zshe seu multios"zshism".

$ echo one > one
$ echo two > two
$ cat one two # cat opens one, shows one, opens two, shows two
one
two
$ cat < one < two # sh opens one then opens two, cat shows stdin (two)
two
$ rm one two
$ echo one > one
$ cat one two # cat opens and shows one, fails to open two
one
cat: two: No such file or directory
$ cat < one < two # the shell opens one then opens two, fails and 
                  # displays an error message, cat gets nothing on stdin
                  # so shows nothing
ksh93: two: cannot open [No such file or directory]

Em um sistema padrão, o shell e catnão tem diferença nos direitos de acesso a arquivos, para que ambos tenham êxito igualmente. Usar sudopara aumentar catos privilégios fará uma grande diferença no comportamento, como Thomas Dickey responde e os comentários em anexo já sugeridos.

jlliagre
fonte
5
Por curiosidade, você realmente usa kshsua própria vontade, e se sim ... por quê ?
gato
11
@cat - essa pergunta é obviamente baseada na ignorância. construa você mesmo e veja.
Mikeerv
2
@mikeserv que se destinava a ser irreverente, não seriamente rude, mas justo o suficiente, eu suponho
gato
2
@cat - eu não suponho o contrário. a ignorância não é algo para se envergonhar - é apenas uma falta de conhecimento. se você não entende por que alguém pode optar por usar o ksh93, posso apenas assumir que é porque você nunca o usou. então eu recomendo que você faça. vale a pena tentar, com certeza. e acredite em mim quando digo que, comparado com bash, ksh93está de longe a melhor concha. é quase a concha.
mikeserv
5
Como o @mikeserv apontou em outro lugar , cat < file1 > file2tem um efeito muito diferente cat file1 > file2do caso em que file1é ilegível ou inexistente. (A última forma trunca file2; a ex não.)
Wildcard
7

cat myfile.txtlê o arquivo e myfile.txtdepois o imprime na saída padrão.

cat < myfile.txtaqui catnão é fornecido nenhum arquivo para abrir, assim como muitos comandos do Unix lêem os dados da entrada padrão, que é direcionada para lá file.txtpelo shell, e imprimem na saída padrão.

Hamza Abbad
fonte
6

A resposta de @Thomas Dickey é brilhante.

Eu só quero adicionar alguns fatos óbvios sobre o caso de ler vários arquivos (vagamente relacionados à sua pergunta, mas ainda assim):

  • cat <file1 <file2 <file3irá ler apenas o arquivo3, pelo menos no bash. (Na verdade, depende do shell, mas a maioria dos shells copia todos os arquivos especificados para stdin, o que faz com que o último seja efetivado.)
  • cat file1 file2 file3lerá todos os arquivos especificados sequencialmente (na verdade, gato é a forma abreviada da palavra concatenar ).
  • cat file1 file2 file3 <file4 <file5 <file6 lerá apenas arquivo1, arquivo2, arquivo3 (como cat ignora stdin quando os argumentos do nome do arquivo são passados).
    • cat file1 file2 - file3 <file4 <file5 <file6 lerá arquivo1, arquivo2, arquivo6, arquivo3 (como o hífen força o gato a não ignorar o stdin).

E sobre erros. No caso de incapacidade de abrir alguns dos arquivos especificados como argumentos (sem <), o gato ignorará os arquivos com falha (com a saída da mensagem relevante para o stderr), mas ainda lerá outros arquivos. No caso de incapacidade de abrir pelo menos um dos arquivos especificados como redirecionamentos (com <), o shell nem iniciará o gato (isso ocorre mesmo para redirecionamentos realmente não usados ​​pelo gato). Nos dois casos, o código de saída incorreto será retornado.

sasha
fonte
11
Observe que, no seu primeiro exemplo, catserá aberto file1e file2, mesmo com file4e file5no seu terceiro exemplo. Apenas mostrará file3, resp. file6conteúdo se essas instruções abertas anteriores tiverem êxito.
jlliagre
@ jlliagre, obrigado, eu não sabia disso. Strace obviamente provou sua correção. Corrigi o texto entre parênteses para os casos 1 e 3a.
Sasha #
0

podemos usar outro comando para perceber a diferença entre:

wc –w food2.txt .

Saída possível:

6 food2.txt .

o comando informa o nome do arquivo desde que o conhece (passado como argumento).

wc –w < food2.txt .

Saída possível:

6 .

a entrada padrão é redirecionada para o arquivo food2.txt sem o comando saber.

user307770
fonte