Por que alguns comandos não recebem redirecionamento de entrada?

4

Por exemplo, echo :

[aesteban@localhost ~]$ cat tmp.txt 
Angel
[aesteban@localhost ~]$ echo < tmp.txt

[aesteban@localhost ~]$

Como você pode ver, a saída é apenas uma linha em branco. De acordo com minhas leituras, alguns comandos podem redirecionar as entradas, por exemplo mail :

[aesteban@localhost ~]$ mail [email protected] < tmp.txt 

O redirecionamento de entrada só se aplica a comandos interativos (aqueles que podem esperar pela entrada)? Como determinar se um comando é interativo (além de tentar)?

    
por angelcool.net 05.06.2015 / 00:04

3 respostas

3

Why some commands don't take input redirection?

A resposta curta: porque eles não foram programados para.

Para um programa ler stdin (que é o fluxo que o shell conecta ao arquivo especificado após < ) não é automático. Precisa ser codificado pelo programador. Aliás, a leitura de arquivos fornecidos na linha de comando também não é automática. Ou seja, o conteúdo desses arquivos, seja dado por redirecionamento ou especificado pelo nome, não aparece magicamente dentro das variáveis do programa sem codificação extra.

Se um programa nunca foi codificado para ler a partir de um fluxo, não importa se você colocou um redirecionamento - simplesmente não lerá dele. Por sua especificação POSIX ( link ), echo não é necessário para ler a partir de stdin e examina apenas seus argumentos de linha de comando (e algumas variáveis de ambiente). Para descobrir outros programas, você pode ler o código-fonte, a documentação ou simplesmente experimentá-lo como você disse: -)

Para responder à sua última pergunta: você não pode realmente dizer que um comando é interativo. Você pode determinar se o fluxo de entrada do qual está lendo está conectado a um terminal (em oposição a, por exemplo, um arquivo simples). Há exemplos em vários idiomas no link . Você pode conceber um programa de correspondência que use esse recurso para determinar se ele está sendo usado interativamente (aceitando comandos de teclado para ler mensagens) ou não interativamente (por exemplo, para ler uma mensagem de correio de um arquivo). Não tenho certeza de como mail faz isso. (Observe que mail se comporta de maneira diferente quando chamado com ou sem argumentos de linha de comando!)

    
por 05.06.2015 / 08:47
1

A maioria dos comandos que lêem o conteúdo de um arquivo (ou arquivos) cujos nomes são especificados na linha de comando lerá da entrada padrão se nenhum arquivo for especificado na linha de comando. Alguns também lerão da entrada padrão se um nome de arquivo de - é especificado na linha de comando; por exemplo,

cat file1 - file2

lerá a partir de file1 , depois a entrada padrão, e, em seguida, file2 . Mas, se um comando normalmente não lê o conteúdo do (s) arquivo (s) cujos nomes são especificados na linha de comando, então provavelmente não fará nada com entrada padrão. echo nunca lê arquivos.

Claro, existem várias exceções:

  • O comando tr sempre lê da entrada padrão, e não aceita nome (s) de arquivo (s) na linha de comando.
  • Se bc for invocado com o (s) argumento (s) de nome de arquivo, ele os lerá e depois também lê a entrada padrão, a menos que um dos arquivos tenha um comando halt ou quit .
  • Compiladores (por exemplo, o compilador C, que pode ser chamado de cc ou gcc ) tendem a exigir (ou pelo menos strongmente preferem) nome (s) de arquivo (s) na linha de comando. cc falhará se for chamado sem nomes de arquivo na linha de comando. cc - lerá a entrada padrão somente se determinadas opções forem especificadas.
  • Não faz sentido invocar cmp ou diff com menos de duas fontes de entrada. Eles falharão se forem invocados sem nomes de arquivos na linha de comando. Ambos honram a convenção que um argumento de - designa a entrada padrão. cmp file1 é equivalente codificar%; ou seja, ele irá comparar cmp file1 - com a entrada padrão. file1 falha se invocado com um argumento de nome de arquivo; você precisaria dizer diff .
  • E, enquanto diff file1 - aceitará uma entrada i f especificada na linha de comando, se for apresentado como dd , por exemplo,

    dd if=my_iso_file of=/dev/sda1
    

    ( if=filename é o utput f ile), e lerá da entrada padrão se você não especificar nenhum of ; por exemplo,

    dd of=/dev/sda1 < my_iso_file
    

    não aceita argumentos da linha de comando que são nomes de arquivos sem adornos (por exemplo, if e dd my_iso_file > /dev/sda1 não não funciona). (Além disso, ao contrário da maioria dos comandos que lêem arquivos, dd my_iso_file of=/dev/sda1 não processará mais de um arquivo de entrada na linha de comando.

(Provavelmente há outros.)

    
por 05.06.2015 / 00:45
0

Leia a documentação.

O comando echo não lê de stdin. Portanto, o redirecionamento de entrada não faz nada. Estados do manual de bash:

echo: Outputs args, separated by spaces, followed by a newline.

Página man de cat :

cat - concatenates files and print on the standard output.

    
por 05.06.2015 / 00:35