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

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

No Bash versão 4.2.47(1)-release, quando tento categorizar o texto formatado que vem de um documento AQUI 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.

Estou tendo o erro a seguir:

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, write <'FOOBAR', porque ainda quero que as variáveis ​​sejam substituídas dentro dele.

Responder1

Esta é uma questão antiga, e como você percebe que este é um exemplo inventado (e, portanto, que a solução correta é usar cat |ou, na verdade, não catneste caso), postarei apenas minha resposta para o caso geral. Eu resolveria isso colocando-o em uma função e usando-a.

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 então use isso

cat <(fmt-func)

Responder2

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 no HEREDOC também parece adequado:

Exemplo - apenas usando um FIFO

Passo #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 que acredito que você está enfrentando é 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 apaziguá-lo um pouco:

Exemplo - escapando de parênteses

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

Mas realmente não dá o que você deseja. Equilibrar os parênteses também parece apaziguá-lo:

Exemplo - balanceamento de parênteses

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

Sempre que tenho strings complexas, como essa para lidar no Bash, quase sempre as construo primeiro, armazenando-as em uma variável, e depois as uso por meio 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
)

Então para imprimir:

$ echo "$var"
(one)
(two

Referências

Responder3

Esta é apenas uma solução alternativa. Pipe fmtto catem vez de usar substituição de 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

informação relacionada