Aqui documento
<< é conhecido como here-document structure. Você deixa o programa saber qual será o texto final, e sempre que esse delimitador é visto, o programa lerá todas as coisas que você deu ao programa como entrada e executará uma tarefa sobre ele.
Veja o que quero dizer:
$ wc << EOF
> one two three
> four five
> EOF
2 5 24
Neste exemplo, dizemos a wc program para esperar por EOF string, digite cinco palavras e, em seguida, digite EOF para sinalizar que terminamos dando entrada. De fato, é semelhante a executar wc , digitando as palavras e pressionando Ctrl D
Aqui string
<<< é conhecido como here-string . Em vez de digitar texto, você fornece uma string de texto pré-criada para um programa. Por exemplo, com um programa como bc , podemos fazer bc <<< 5*4 para obter a saída para esse caso específico, sem necessidade de executar bc interativamente.
Substituição de processos
Como tldp.org explica,
A substituição de processos alimenta a saída de um processo (ou processos) em o stdin de outro processo.
Portanto, de fato, isso é semelhante à canalização stdout de um comando para o outro, por exemplo, echo foobar barfoo | wc . Mas observe: na bash manpage você verá que é denotado como <(list) . Então, basicamente, você pode redirecionar a saída de vários comandos (!).
Observação: tecnicamente quando você diz < < não está se referindo a uma coisa, mas dois redirecionamentos com < único e redirecionamento de processo de saída de <( . . .) .
Agora, o que acontece se apenas processarmos a substituição?
$ echo <(echo bar)
/dev/fd/63
Como você pode ver, o shell cria um descritor de arquivo temporário /dev/fd/63 para onde a saída vai. Isso significa que < redireciona esse descritor de arquivo como entrada para um comando.
Um exemplo muito simples seria fazer a substituição do processo de saída de dois comandos de echo em wc:
$ wc < <(echo bar;echo foo)
2 2 8
Então, aqui fazemos o shell criar um descritor de arquivo para toda a saída que acontece nos parênteses e redirecionar como entrada para wc . Como esperado, wc recebe esse fluxo de dois comandos de eco, que por si só produziria duas linhas , cada um com uma palavra e, apropriadamente, temos 2 palavras, 2 linhas e 6 caracteres, mais duas novas linhas contadas.
Nota: A substituição do processo pode ser chamada de bashism (um comando ou estrutura utilizável em shells avançados como bash , mas não especificado pelo POSIX), mas foi implementado em ksh antes da existência do bash como página do manual do ksh e esta resposta sugere.
No entanto, shells como tcsh e mksh não possuem substituição de processo. Então, como poderíamos sair por aí redirecionando a saída de múltiplos comandos para outro comando sem a substituição do processo? Agrupamento mais tubulação!
$ (echo foo;echo bar) | wc
2 2 8
Efetivamente isto é o mesmo que o exemplo acima, No entanto, isso é diferente sob o capô da substituição de processo, já que fazemos stdout dos comandos agrupados e stdin de wc vinculado ao pipe . Por outro lado, a substituição do processo faz com que um comando leia um descritor de arquivo temporário.
Então, se podemos fazer o agrupamento com tubulação, por que precisamos de substituição de processo? Porque às vezes não podemos usar tubulação. Considere o exemplo abaixo - comparando as saídas de dois comandos com diff (que precisa de dois arquivos e, neste caso, estamos dando a ele dois descritores de arquivo)
diff <(ls /bin) <(ls /usr/bin)