Як поєднати підстановку процесу Баша з документом ТУТ?


14

У Bash версії 4.2.47 (1) -випустіть, коли я намагаюся катетувати відформатований текст, який надходить з DUE-символу ТУТ:

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-документ, тобто писати <'FOOBAR', тому що я все ще хочу, щоб в ньому були замінені змінні.


Вам справді потрібен catдзвінок? Чому б не залишити його при дзвінку fmt?
iruvar

2
Мушу визнати, що це надуманий приклад. Мої фактичні потреби є складнішими за них.
Тім Фріске

1
Цікаво , що при заміні (Evenз "(Even"його роботою. Це те ж саме для \(Even. Схоже на помилку розбору. Bash все ще знаходиться в контексті, якщо він шукає дужки, в той час як і в контексті читання тут документа, і обидва контексти суперечать один одному.
Рафаель Аренс

1
Це зафіксовано в bash4.3.
чепнер

Відповіді:


7

Процес заміщення приблизно еквівалентний цьому.

Приклад - механіка заміщення процесу

Крок №1 - зробіть фіфо, виведіть на нього

$ mkfifo /var/tmp/fifo1
$ fmt --width=10 <<<"$(seq 10)" > /var/tmp/fifo1 &
[1] 5492

Крок №2 - прочитайте фіфо

$ 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

Проблема, я вважаю, що ви стикаєтеся з тим, що заміщення процесу, <(...)схоже, не піклується про вкладення паронів всередині нього.

Приклад - процес 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

1
Я спробував ваш "спосіб вирішення", і це спрацювало б для мене. Спасибі. Але все ж я хочу зрозуміти, чому моя комбінація документа HERE, вкладеного всередині заміни процесу, не працює. Ви отримали відповідь?
Тім Фріске

@TimFriske, мені доведеться відкласти це одному з bashмайстрів на цьому сайті. Мої знання внутрішніх інструментів
basse

2

Це старе питання, і коли ви розумієте, що це надуманий приклад (і, таким чином, правильне рішення - використовувати 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)

Дякую! Саме те, що я шукав.
piarston
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.