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 (geralmente definida por PATH) e não houver mais caracteres especiais (depende do shell que você está usando), todas as palavras subsequentes separadas por espaços ou tabulações serão passadas para o programa de uma forma especial, ou seja, uma matriz. Com cada palavra como um elemento na matriz.
Como o programa que você vai chamar interpreta os argumentos (localizados na matriz) depende de como ele é programado. Existem alguns padrões para a aparência da sintaxe dos argumentos, mas em geral o programador é totalmente gratuito. Portanto, o primeiro argumento pode ser interpretado como o nome de um arquivo ou qualquer que seja o pensamento do programador na época em que ele escreveu o programa.
No caso de você adicionar o carácter especial <ou >a sua linha de comando, o acréscimo shell dosn't <e >nem palavras subseqüentes para a matriz que será passado para o programa. Com <ou >dado, o shell começa a criar coisas sofisticadas, suportadas pelo kernel subjacente ( canal de palavras-chave ). Para entender o que está acontecendo, você deve entender o que STDINe STDOUT(já que não está imediatamente relacionado, eu omito STDERR) são.
Tudo o que você vê no seu terminal (na maioria dos casos, parte do seu monitor) é gravado pelo shell ou por qualquer outro programa que você chamou anteriormente em um arquivo especial (no unix, tudo é um arquivo ). Este arquivo tem um ID especial e é chamado STDOUT. Se um programa deseja ler dados do teclado, ele não pesquisa diretamente o teclado (pelo menos na maioria dos casos), mas lê de um arquivo especial chamado STDIN. Internamente, esse arquivo está conectado ao seu dispositivo de entrada padrão, seu teclado na maioria dos casos.
Se o shell lê <ou >em uma linha de comando analisada, ele manipula STDINou STDOUTde um tipo específico pelo tempo em que o programa correspondente está sendo executado. STDINe STDOUTnão aponte mais para o terminal ou o dispositivo de entrada padrão, mas para o nome do arquivo subsequente na linha de comando.
No caso das duas linhas
cat file_name
cat < file_name
o comportamento observado é idêntico porque o desenvolvedor correspondente faz catpara ler dados STDINou ler os dados do arquivo, cujo nome é dado como o primeiro argumento da linha de comando (que é o primeiro elemento na matriz para a qual o shell passa cat). Posteriormente, catgrava todo o conteúdo de file_nameou STDINpara o terminal, pois não instruímos o shell a manipular STDOUT. Lembre-se de que na segunda linha seu shell manipula STDINdessa maneira, que não aponta mais para o seu dispositivo de entrada padrão, mas aponta para um arquivo chamado file_nameno seu diretório de trabalho atual.
No outro caso da linha
man < file_name
mannão pretende ler nada, STDINse for chamado sem argumento, ou seja, uma matriz vazia. Então a linha
man < file_name
é igual a
man
Por exemplo, mantambém lerá algo de STDINse você passar -l -para man. Com esta opção fornecida na linha de comando, você pode exibir o conteúdo de qualquer coisa manlida STDINno seu terminal. então
man -l - < file_name
funcionaria também (mas tenha cuidado mannã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 STDIN, como STDOUTe os argumentos da linha de comando são interpretados, tudo depende do desenvolvedor correspondente.
Espero que minha resposta possa esclarecer as coisas.
man -l - < file_nameparamaninterpretarSTDINcomo argumentos, mas ele falha no meu sistema com oSTDERR:man -l - < tee man: invalid option -- l man, version 1.6c