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