Bashのプロセス置換をHEREドキュメントと組み合わせるには?

Bashのプロセス置換をHEREドキュメントと組み合わせるには?

Bashバージョン4.2.47(1)リリースでは、次のようにHERE文書のリッチテキストをリンクしようとすると、次のようになります。

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

あなたが経験している問題は、プロセス置換が<(...)その中に角かっこ入れ子を気にしないようです。

はい - プロセスサブ+ 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

関連情報