Como combinar a substituição de processos do Bash com o documento AQUI?

10

No Bash versão 4.2.47 (1) - libere quando eu tento catenar o texto formatado que vem de um HERE-dcoument da seguinte forma:

cat <(fmt --width=10 <<FOOBAR
(I want the surrounding parentheses to be part of the HERE-document)
(Even the preceding unbalanced parenthesis should be part of it.
FOOBAR
) # I want this paranthesis to end the process substitution.

Eu recebo o seguinte erro:

bash: bad substitution: no closing ')' in <(fmt --width=10 <<FOOBAR
(I want the surrounding parentheses to be part of the HERE-document)
(Even the preceding unbalanced parenthesis should be part of it.
FOOBAR
)

Além disso, não quero citar o documento AQUI, ou seja, escreva <'FOOBAR' , porque ainda quero que as variáveis sejam substituídas por ele.

    
por Tim Friske 17.06.2014 / 02:49

3 respostas

5

A substituição do processo é aproximadamente equivalente a isso.

Exemplo - mecânica de substituição de processo

Passo # 1 - faça um fifo, envie para ele

$ mkfifo /var/tmp/fifo1
$ fmt --width=10 <<<"$(seq 10)" > /var/tmp/fifo1 &
[1] 5492

Passo # 2 - leia o fifo

$ cat /var/tmp/fifo1
1 2 3 4
5 6 7 8
9 10
[1]+  Done                    fmt --width=10 <<< "$(seq 10)" > /var/tmp/fifo1

O uso de parênteses dentro do HEREDOC também parece OK:

Exemplo - usando apenas um FIFO

Etapa # 1 - saída para FIFO

$ fmt --width=10 <<FOO > /var/tmp/fifo1 &
(one)
(two
FOO
[1] 10628

Passo # 2 - leia o conteúdo do FIFO

$ cat /var/tmp/fifo1
(one)
(two

O problema, acredito que você está se deparando é que a substituição do processo, <(...) , não parece se importar com o aninhamento de parênteses dentro dele.

Exemplo - processo sub + HEREDOC não funciona

$ cat <(fmt --width=10 <<FOO
(one)
(two
FOO
)
bash: bad substitution: no closing ')' in <(fmt --width=10 <<FOO
(one)
(two
FOO
)
$

Escapar dos parênteses parece satisfazê-lo um pouco:

Exemplo - parênteses fugitivos

$ cat <(fmt --width=10 <<FOO                 
\(one\)
\(two
FOO
)
\(one\)
\(two

Mas realmente não te dá o que você quer. Tornar os parentes equilibrados também parece apaziguá-lo:

Exemplo - balanceamento de parentes

$ cat <(fmt --width=10 <<FOO
(one)
(two)
FOO
)
(one)
(two)

Sempre que eu tenho strings complexas, como essa para lidar com o Bash, eu quase sempre as construo primeiro, armazenando-as em uma variável, e então as uso através da variável, em vez de tentar criar um liner complicado que acaba sendo frágil.

Exemplo - use uma variável

$ var=$(fmt --width=10 <<FOO
(one)
(two
FOO
)

Em seguida, imprima:

$ echo "$var"
(one)
(two

Referências

por 17.06.2014 / 10:51
1

Esta é apenas uma solução alternativa. Pipe fmt to cat em vez de usar a substituição do processo

fmt --width=10 <<FOOBAR | cat 
(I want the surrounding parentheses to be part of the HERE-document)
(Even the preceding unbalanced parenthesis should be part of it.
FOOBAR
    
por 17.06.2014 / 02:55
1

Essa é uma pergunta antiga e, como você percebe que esse é um exemplo artificial (e, portanto, que a solução correta é usar cat | ou, na verdade, nenhum cat nesse caso), postar minha resposta para o caso geral. Eu resolveria isso colocando-o em uma função e usando isso.

fmt-func() {
    fmt --width=10 <<FOOBAR
(I want the surrounding parentheses to be part of the HERE-document)
(Even the preceding unbalanced parenthesis should be part of it.
FOOBAR
}

e depois use isso

cat <(fmt-func)
    
por 31.10.2015 / 13:02