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)