Como este comando é legal? “Arquivo1 arquivo2 gato”

55

Assumindo que file2 já exista, o comando

> file1 < file2 cat

parece estar copiando o conteúdo de file2 para file1 .

Mas não consigo entender essa estrutura.

Entendo que "Nothing" está sendo direcionado para file1 (criando ou apagando seu conteúdo). Em seguida, o conteúdo de file2 está sendo direcionado para file1 .

Por que cat após file2 ? como ele sabe para cat file2 se os operandos não estão na ordem correta?

    
por shaqed 05.04.2017 / 14:42

1 resposta

107

Antes de o shell executar o comando cat na linha de comando, ele procura por redirecionamentos.

Existem dois redirecionamentos:

  1. >file1 Isso fará com que a saída padrão do comando vá para file1 .
  2. <file2 Isso fará com que a entrada padrão do comando venha de file2 .

O fato de que esses redirecionamentos são colocados em um local incorreto 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 utilitário cat em todas essas instâncias é executado sem nenhum argumento de linha de comando . Os redirecionamentos não são operandos para o comando cat , são instruções para o shell configurar redirecionamentos para dentro e para fora do comando (conectando sua entrada e saída padrão aos arquivos). O shell configura os redirecionamentos antes invocando o comando.

A diferença entre cat file e cat <file (ou, se você for, <file cat ) é que, no primeiro caso, o utilitário cat está abrindo o arquivo, que é fornecido como um operando no arquivo. linha de comando, para leitura, enquanto no segundo caso, o shell abrirá o arquivo e conectará o fluxo de entrada do cat a ele². No segundo caso, cat notará que não foi dado um operando de arquivo e mudará automaticamente para a leitura de sua entrada padrão. Esse é um recurso do cat e de 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 (isto é, nada que o shell faça). Para usar cat em um arquivo no diretório atual cujo nome é - , inclua um caminho para o nome do arquivo, como ./- .

¹ A ordem dos redirecionamentos ainda é importante sob algumas circunstâncias; Com cat <file2 >file1 , por exemplo, file1 não será truncado se file2 estiver inacessível (os redirecionamentos serão analisados da esquerda para a direita). O posicionamento relativo da palavra cat , no entanto, ainda é arbitrário e não influenciará isso.

² Veja também a pergunta " cat dá um erro diferente ao abrir o arquivo não existente ".

O fato de que o shell configura os redirecionamentos antes mesmo de executar o comando na linha de comando é o motivo pelo qual coisas como essas falham e você acaba com um arquivo de saída vazio:

$ sort file >file

Aqui, o shell irá truncar (esvaziar) o arquivo file antes de executar sort file e conectar a saída padrão de sort ao arquivo. O utilitário sort abrirá file e classificará seu conteúdo (que não é nada). O resultado (nada) é passado pelo fluxo de saída padrão para file .

O remédio neste 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 arquivo -o para especificar o nome do arquivo de saída.

Apenas para fazer o backup da declaração de que os redirecionamentos podem preceder o nome real do utilitário na linha de comando:

A "simple command" is a sequence of optional variable assignments and redirections, in any sequence, optionally followed by words and redirections, terminated by a control operator. [ref: POSIX Shell Command Language 2.9.1 Simple Commands]

E também sobre o redirecionamento não fazer parte dos operandos do utilitário:

The optional number, redirection operator, and word shall not appear in the arguments provided to the command to be executed (if any). [ref: POSIX Shell Command Language 2.7 Redirection]

    
por 05.04.2017 / 14:47