É possível usar vários documentos aqui no bash?


14

Pode-se usar vários documentos aqui para fornecer entrada para um comando no bash?

$ cat <<<foo <<<bar
bar
$ cat <<EOF1 <<EOF2
> foo
> EOF1
> bar
> EOF2
bar

Obviamente, em ambos os casos, o segundo documento aqui é usado como stdin e substitui a primeira referência. A solução echoé usar s em vez disso?

$ cat <(echo -n foo) <(echo bar)
foobar

Além disso, por algum motivo, o uso de uma combinação não funcionou para mim. Por que isso seria?

$ cat <<<foo <(echo bar)
bar
$ cat <(echo -n foo) <<<bar
foo

Existe alguma razão por trás do fato de que você deseja usar dois documentos aqui em vez de combiná-los em um?
— feijão

1
@beans Na verdade, eu o encontrei ao testar pastecom entradas falsas. Suponho que posso pensar em alguns outros cenários. Se eu tivesse um script com texto pré-manipulado em algumas variáveis, talvez eu queira fazer algo para ambos com um comando que usa apenas arquivos, por exemplo diff.
— Sparhawk

Outro caso de uso (eu achei isso usando aqui-docs para criar um script shell): você quer algumas linhas com a expansão de variáveis e, em seguida, algumas linhas sem: cat <<EOF1 <<"EOF2".
— precisa saber é o seguinte

Respostas:


18

Você pode fazer:

cat /dev/fd/3 3<< E1 /dev/fd/4 4<< E2
foo
E1
bar
E2

Pode haver apenas um stdin, pois há apenas um descritor de arquivo 0.

cat << EOF
eof
EOF

é a abreviação de:

cat /dev/fd/0 0<< EOF
eof
EOF

E:

cat <<< foo

é:

cat /dev/fd/0 0<<< foo

Você deve decidir o que abrir no descritor de arquivo 0.

cat <(echo foo)

É:

cat /dev/fd/123

Onde 123está um descritor de arquivo para um canal e, paralelamente, o bash é executado echo fooem outro processo com o stdout redirecionado para a outra extremidade do canal.

Depois de passar um nome de arquivo para cat, catnão leia mais do stdin. Você precisaria de:

cat <(echo foo) /dev/fd/0 << EOF
bar
EOF

Ou:

cat <(echo foo) - << EOF
bar
EOF

( -é dizer catpara ler de stdin).


1
cat <<EOFnão é exatamente o mesmo que cat /dev/fd/0...: no último caso, catvê o nome do arquivo e abre.
— Mikel

@ Mikel, o que eu quis dizer é que é funcionalmente equivalente . Quando não é passado nenhum argumento, catlê seu fd0, como se tivesse passado um argumento de ( -ou apenas /dev/fd/0no Linux (e Linux)), a abertura /dev/fd/0não é exatamente como duplicar o descritor de arquivo 0).
— Stéphane Chazelas

Fiquei muito surpreso com a /dev/fd/3 3<< E1construção e agora me pergunto o que exatamente são os itens em / dev / fd /. Embora eles de alguma forma pareçam mágicos após o processo abrir um arquivo em algum lugar do sistema de arquivos, com a exceção de 1 e 2, que existem por padrão para todos os processos. Mas, no seu exemplo, você está usando o descritor de arquivo 3 e 4 que não está conectado a nenhum arquivo real, exceto pelo redirecionamento de entrada. Não consigo compreender isso no meu modelo mental de descritores de arquivos. E se o processo quiser abrir outro arquivo, ele saberia que precisa usar o fd 5? Fds tem que ser 3, 4, 5 .. ou pode ser qualquer coisa?
— Calavera.info

@ calavera.info, parece que você deseja criar uma pergunta de acompanhamento.
— Stéphane Chazelas
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.