Sua pergunta está intimamente relacionada a como o shell que você está usando analisa a entrada do usuário na linha de comando.
Se a primeira palavra na linha de comando for um programa, localizado em uma pasta especial (definida principalmente por PATH
) e nenhum caractere especial for fornecido (depende do shell que você está usando), todas as palavras subsequentes serão separadas por espaços ou tabulações são passados para o programa de uma forma especial, isto é, uma matriz. Com cada palavra como um elemento na matriz.
Como o programa, você vai chamar interpreta os argumentos (localizados na matriz) depende de como ele é programado. Existem alguns padrões quase de como a sintaxe dos argumentos deve parecer, mas em geral o programador é totalmente livre. Assim, o primeiro argumento pode ser interpretado como um nome de um arquivo ou qualquer que seja o pensamento do programador no momento em que ele escreveu o programa.
Caso você adicione o caractere especial <
ou >
à sua linha de comando, o shell não adicionará <
e >
nem as palavras subsequentes à matriz que será passada para o programa. Com <
ou >
dado o shell começa a fazer coisas sofisticadas, suportado pelo kernel subjacente (keyword piping ). Para entender o que está acontecendo, você deve entender o que é STDIN
e STDOUT
(já que não está imediatamente relacionado omitido STDERR
).
Tudo o que você vê no seu terminal (na maioria dos casos, uma parte do seu monitor) é escrito pelo shell ou qualquer outro programa que você tenha chamado anteriormente para um arquivo especial (em unix tudo é um arquivo ). Este arquivo tem um id especial e é chamado de STDOUT
. Se um programa desejar ler dados do teclado, ele não pesquisará o teclado diretamente (pelo menos na maioria dos casos), mas lerá de um arquivo especial chamado STDIN
. Internamente, este arquivo é conectado ao seu dispositivo de entrada padrão, seu teclado na maioria dos casos.
Se o shell ler <
ou >
em uma linha de comando analisada, ele manipula STDIN
ou STDOUT
em um tipo específico durante o tempo em que o programa correspondente está sendo executado. STDIN
e STDOUT
não apontam para o terminal ou para o dispositivo de entrada padrão, mas sim para o nome de arquivo subseqüente na linha de comando.
No caso das duas linhas
cat file_name
cat < file_name
o comportamento observado é idêntico porque o desenvolvedor correspondente transforma cat
em ler dados de STDIN
ou ler os dados do arquivo, cujo nome é dado como o primeiro argumento de linha de comando (que é o primeiro elemento no array o shell passa para cat
). Subsequentemente, cat
grava todo o conteúdo de file_name
ou STDIN
no terminal, pois não instruímos o shell a manipular STDOUT
. Lembre-se que na segunda linha seu shell manipula STDIN
desta forma, que ele não aponta para seu dispositivo de entrada padrão anylonger, mas aponta para um arquivo chamado file_name
em seu diretório de trabalho atual.
No outro caso da linha
man < file_name
man
não deve ler nada de STDIN
se for chamado sem argumento, ou seja, uma matriz vazia. Então a linha
man < file_name
é igual a
man
Por exemplo, man
lerá algo de STDIN
, também se você passar -l -
para man
. Com esta opção dada na linha de comando você pode exibir o conteúdo de qualquer coisa man
lê STDIN
no seu terminal. Então
man -l - < file_name
também funcionaria (mas tenha cuidado, man
não é apenas um pager, mas também analisa a entrada do arquivo e, portanto, o conteúdo do arquivo e o conteúdo exibido podem ser diferentes).
Então, como STDIN
, STDOUT
e os argumentos da linha de comando são interpretados, tudo depende do desenvolvedor correspondente.
Espero que minha resposta possa esclarecer as coisas.