Eu estava trabalhando em um tutorial e vi o uso de ambos cat myfile.txt
e cat < myfile.txt
. Existe uma diferença entre essas duas sequências de comandos? Parece que ambos imprimem o conteúdo de um arquivo no shell.
Eu estava trabalhando em um tutorial e vi o uso de ambos cat myfile.txt
e cat < myfile.txt
. Existe uma diferença entre essas duas sequências de comandos? Parece que ambos imprimem o conteúdo de um arquivo no shell.
Respostas:
No primeiro caso, cat
abre o arquivo e, no segundo caso, o shell abre o arquivo, passando-o como cat
entrada 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 cat
programa. 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 cat
não é o mesmo programa.
sudo cat myfile.txt
. Mas sudo cat < myfile.txt
não funcionará se você não tiver privilégios para ler o arquivo.
ksh93
foi cat
embutido (não ativado por padrão, a menos que você tenha /opt/ast/bin
no início $PATH
).
wc
imprimirá o nome do arquivo antes da contagem quando houver um argumento.
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.txt
no diretório atual ou se você não tiver permissão para lê-lo.
No primeiro caso, cat
irá reclamar e, no último caso, seu shell mostrará claramente qual processo está tentando abrir o arquivo, cat
no 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 cat
menos que você use zsh
e 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 cat
não tem diferença nos direitos de acesso a arquivos, para que ambos tenham êxito igualmente. Usar sudo
para aumentar cat
os privilégios fará uma grande diferença no comportamento, como Thomas Dickey responde e os comentários em anexo já sugeridos.
ksh
sua própria vontade, e se sim ... por quê ?
bash
, ksh93
está de longe a melhor concha. é quase a concha.
cat < file1 > file2
tem um efeito muito diferente cat file1 > file2
do caso em que file1
é ilegível ou inexistente. (A última forma trunca file2
; a ex não.)
cat myfile.txt
lê o arquivo e myfile.txt
depois o imprime na saída padrão.
cat < myfile.txt
aqui cat
nã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.txt
pelo shell, e imprimem na saída padrão.
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 <file3
irá 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 file3
lerá 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.
cat
será aberto file1
e file2
, mesmo com file4
e file5
no seu terceiro exemplo. Apenas mostrará file3
, resp. file6
conteúdo se essas instruções abertas anteriores tiverem êxito.
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.