在 Bash 版本 4.2.47(1)-release 中,当我尝试连接来自 HERE-doument 的格式化文本时,如下所示:
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.
我收到以下错误:
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
)
另外,我不想引用 HERE 文档,即 write <'FOOBAR'
,因为我仍然希望在其中替换变量。
答案1
这是一个老问题,当您意识到这是一个人为的示例(因此正确的解决方案是使用cat |
或实际上,cat
在这种情况下根本不使用)时,我将发布我对一般情况的答案。我会通过将其放入一个函数中并使用它来解决它。
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
}
然后用它
cat <(fmt-func)
答案2
流程替换大致相当于这个。
示例 - 进程替换的机制
步骤#1-制作一个fifo,并将输出输出到它
$ mkfifo /var/tmp/fifo1
$ fmt --width=10 <<<"$(seq 10)" > /var/tmp/fifo1 &
[1] 5492
步骤#2 - 读取 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
在 HEREDOC 中使用括号似乎也可以:
示例 - 仅使用 FIFO
步骤#1 - 输出到 FIFO
$ fmt --width=10 <<FOO > /var/tmp/fifo1 &
(one)
(two
FOO
[1] 10628
步骤#2 - 读取 FIFO 的内容
$ cat /var/tmp/fifo1
(one)
(two
我相信您遇到的麻烦是进程替换<(...)
似乎并不关心其中括号的嵌套。
示例 - process sub + HEREDOC 不起作用
$ cat <(fmt --width=10 <<FOO
(one)
(two
FOO
)
bash: bad substitution: no closing `)' in <(fmt --width=10 <<FOO
(one)
(two
FOO
)
$
转义括号似乎稍微安抚了它:
示例 - 转义括号
$ cat <(fmt --width=10 <<FOO
\(one\)
\(two
FOO
)
\(one\)
\(two
但并没有真正给你你想要的。使括号平衡似乎也可以安抚它:
示例 - 平衡括号
$ cat <(fmt --width=10 <<FOO
(one)
(two)
FOO
)
(one)
(two)
每当我有复杂的字符串(例如在 Bash 中要处理的字符串)时,我几乎总是会先构造它们,将它们存储在变量中,然后通过变量使用它们,而不是尝试制作一些最终会被脆弱的。
示例 - 使用变量
$ var=$(fmt --width=10 <<FOO
(one)
(two
FOO
)
然后打印它:
$ echo "$var"
(one)
(two
参考
答案3
这只是一个解决方法。管道fmt
到cat
而不是使用进程替换
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