Quando devo usar ou () ou e ou ()?

4

Eu sei que < , <() , << all são usados para fornecer entrada e > , >() , que são usados para redirecionar a saída.

Mas eu não sei o que é diferença clara entre eles e quando usá-los. Por favor, explique em detalhes e junto com as referências, se possível. Obrigado

    
por Edward Torvalds 12.11.2015 / 12:24

2 respostas

12

"Quando usar" é realmente dependente do que você está fazendo. É como perguntar quando usar um Phillips ou uma chave de fenda. Eu posso te dizer o que todos eles são, e o que eles fazem, mas trabalhar quando você usa cada um, é com você.

Tudo isso está amplamente documentado no Guia avançado de script basculante do TLDP . Se você precisar de exemplos, esse é o lugar.

  • < filename lê de um arquivo para STDIN
  • > filename escreve STDOUT para o arquivo, sobrescrevendo qualquer coisa.
  • >> filename escreve STDOUT para arquivar, anexando se já existe.
  • <(command) absorve a saída do comando interno e fornece um nome de arquivo
  • >(command) fornece um nome de arquivo para o comando externo, mas na verdade redireciona qualquer coisa escrita para ele no STDIN do command interno.
  • <<TOKEN é um documento aqui, também conhecido como heredoc. Ele lerá qualquer coisa a seguir em STDIN até ver TOKEN novamente. É útil para conteúdo de várias linhas. Tem que ser seguido por uma nova linha. A menos que você cite o token, heredocs suportam a substituição de variáveis.
  • <<-TOKEN é como acima, exceto que ele ignorará as guias principais (mas apenas as guias). Isso é útil para preservar a formatação de origem, mas ela realmente funciona apenas com guias. Ele é inutilizado nos sites do Stack Exchange porque eles substituem as guias por espaços: (
  • <<"TOKEN" é um heredoc que não substituirá $variables .
  • <<<"string" é um heredring. É lido em STDIN. Isso pode fazer a substituição de variáveis.
  • | command une o STDOUT atual ao STDIN de command
  • |& command une STDOUT e STDERR no STDIN de command (útil para a saída de erros do grep)
  • 1> e 2> são usados para redirecionar explicitamente STDOUT e STDERR. > implica 1> , por isso você raramente o vê usado explicitamente.
  • Em uma veia semelhante, >&1 e >&2 podem ser usados para redirecionar para STDOUT e STDIN.
  • /dev/std{in,out,err} também existem como links simbólicos para os descritores de arquivos básicos de entrada / saída / erro. Isso é útil quando algo só aceita um argumento de nome de arquivo, mas você quer que ele grave em STDOUT, por exemplo.
por Oli 12.11.2015 / 12:30
2

A resposta de Oli já fornece muita explicação. Meu propósito nesta resposta é fornecer vários exemplos práticos.

Digite o redirecionamento com [comando] < arquivo

O redirecionamento < serve para enviar a saída de um arquivo para um comando. Se você puder imaginar, o fio virtual é desconectado do teclado e conectado ao arquivo. Funciona bem quando você não quer usar canos ou não pode usar canos.

Por exemplo, suponha que eu tenha uma lista de arquivos. Eu quero executar algum tipo de teste em cada nome de arquivo (talvez verificar se o arquivo existe ou é um arquivo específico).

 while read FILENAME; do [ -d $FILENAME  ] && echo $FILENAME;done < fileList.txt

Normalmente, esse comando como read recebe entrada de STDIN, mas usando o operador < , fazemos com que seja necessário inserir o arquivo.

Aqui documento < <

Isso é muito útil quando você deseja operar na saída de outro comando ou de vários comandos, mas não deseja criar um arquivo.

Na minha resposta a Qual é a diferença entre < & lt ;, < < < e < < no bash? , mostrei dois exemplos simples wc < <(echo bar;echo foo) e diff <(ls /bin) <(ls /usr/bin) . O último é especialmente útil - estamos comparando as saídas de dois comandos sem nunca criar um arquivo para armazenar os dados a serem comparados.

Redirecionamento com COMMAND1 > > (COMMAND2)

Este é equivalente a tubulação.

xieerqi@eagle:~$ df > >(grep "dev" )
xieerqi@eagle:~$ /dev/sda1      115247656 83004376  26365932  76% /
udev             2914492        4   2914488   1% /dev

Como mostrado na wiki do Greg , isso pode ser usado para dar a mesma entrada  para vários comandos

some_command | tee >(grep A > A.out) >(grep B > B.out) >(grep C > C.out) > /dev/null
    
por Sergiy Kolodyazhnyy 12.11.2015 / 17:49