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 cat
neste 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 fmt
to cat
em 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