如何將 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

相關內容