Antes de o shell executar o cat
comando na linha de comando, ele procura por redirecionamentos.
Existem dois redirecionamentos:
>file1
Isso fará com que a saída padrão do comando vá para file1
.
<file2
Isso fará com que a entrada padrão do comando venha file2
.
O fato de esses redirecionamentos serem colocados em um local instável na linha de comando não importa.
$ cat <file2 >file1
é o mesmo que
$ <file2 cat >file1
que é o mesmo que
$ <file2 >file1 cat
etc.¹
Observe que o cat
utilitário em todas essas instâncias é executado sem nenhum argumento de linha de comando . Os redirecionamentos não são operandos para o cat
comando, são instruções para o shell para configurar redirecionamentos para dentro e fora do comando (conectando sua entrada e saída padrão aos arquivos). O shell configura os redirecionamentos antes de chamar o comando.
A diferença entre cat file
e cat <file
(ou, se você preferir <file cat
) é que, no primeiro caso, o cat
próprio utilitário está abrindo o arquivo, que é fornecido como um operando na linha de comando, para leitura, enquanto no segundo caso, o shell irá abra o arquivo e conecte cat
o fluxo de entrada a ele². No segundo caso, cat
notará que não recebeu um operando de arquivo e passará automaticamente para a leitura de sua entrada padrão. Esse é um recurso cat
e alguns outros utilitários, não algo que todos os utilitários fazem.
cat
também lerá sua entrada padrão se receber o operando -
. Novamente, isso é especial apenas para cat
e para alguns outros utilitários (ou seja, nada que o shell faça). Para usar cat
em um arquivo no diretório atual cujo nome é -
, adicione um caminho ao nome do arquivo, como ./-
.
¹ A ordem dos redirecionamentos ainda é importante em algumas circunstâncias; Com cat <file2 >file1
, por exemplo, file1
não será truncado se file2
estiver inacessível (os redirecionamentos são analisados da esquerda para a direita). A colocação relativa da palavra cat
ainda é arbitrária e não influenciará isso.
² Veja também a pergunta " cat dá erro diferente ao abrir arquivo inexistente ".
O fato de o shell configurar os redirecionamentos antes mesmo de executar o comando na linha de comando é o motivo pelo qual essas coisas falham e você acaba com um arquivo de saída vazio:
$ sort file >file
Aqui, o shell truncará (esvaziará) o arquivo file
antes de executar sort file
e conectar sort
a saída padrão do arquivo. O sort
utilitário abrirá file
e classificará seu conteúdo (o que não é nada). O resultado (nada) é passado pelo fluxo de saída padrão para file
.
O remédio nesse caso específico (para classificar um arquivo "no local") é
$ sort -o file file
ou
$ sort file >file.sorted && mv file.sorted file
que é mais ou menos o que sort
faz ao usar o -o
arquivo para especificar o nome do arquivo de saída.
Apenas para fazer backup da declaração de que os redirecionamentos podem preceder o nome real do utilitário na linha de comando:
Um "comando simples" é uma sequência de atribuições e redirecionamentos de variáveis opcionais, em qualquer sequência, opcionalmente seguidos por palavras e redirecionamentos, finalizados por um operador de controle. [ref: POSIX Shell Command Language 2.9.1 Comandos Simples]
E também sobre o redirecionamento não fazer parte dos operandos do utilitário:
O número opcional, o operador de redirecionamento e a palavra não devem aparecer nos argumentos fornecidos ao comando a ser executado (se houver). [ref: Redirecionamento da linguagem de comando do shell POSIX 2.7]