如何将 Bash 的进程替换与 HERE-document 结合起来?

如何将 Bash 的进程替换与 HERE-document 结合起来?

在 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

这只是一个解决方法。管道fmtcat而不是使用进程替换

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

相关内容