É 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
Sparhawk
fonte
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).

Stéphane Chazelas
fonte
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