Làm cách nào để kết hợp thay thế quy trình của Bash với tài liệu TẠI ĐÂY?


14

Trong phiên bản Bash 4.2.47 (1) - hãy giải phóng khi tôi cố gắng catenate văn bản được định dạng xuất phát từ ĐÂY-dcoument như vậy:

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.

Tôi nhận được lỗi sau đây:

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
)

Ngoài ra tôi không muốn trích dẫn tài liệu TẠI ĐÂY, tức là viết <'FOOBAR', bởi vì tôi vẫn muốn có các biến được thay thế trong đó.


Bạn có thực sự cần catcuộc gọi? Tại sao không để nó ở cuộc gọi fmt?
iruvar

2
Tôi phải thừa nhận nó là một ví dụ giả định. Nhu cầu thực tế của tôi phức tạp hơn thế.
Tim Friske

1
Điều thú vị là khi bạn thay thế (Evenbằng "(Even"nó hoạt động. Nó là như nhau cho \(Even. Trông giống như một lỗi phân tích cú pháp. Bash vẫn còn trong một bối cảnh là nó đang tìm kiếm niềng răng trong khi trong bối cảnh đọc tài liệu ở đây và cả hai bối cảnh mâu thuẫn với nhau.
Raphael AhDR

1
Điều này được cố định trong bash4.3, tình cờ.
chepner

Câu trả lời:


7

Sự thay thế quá trình là tương đương với điều này.

Ví dụ - cơ học của quá trình thay thế

Bước # 1 - tạo một fifo, xuất ra nó

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

Bước # 2 - đọc 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

Việc sử dụng parens trong HEREDOC cũng có vẻ ổn:

Ví dụ - chỉ cần sử dụng một FIFO

Bước # 1 - xuất ra FIFO

$ fmt --width=10 <<FOO > /var/tmp/fifo1 &
(one)
(two
FOO
[1] 10628

Bước # 2 - đọc nội dung của FIFO

$ cat /var/tmp/fifo1
(one)
(two

Vấn đề, tôi tin rằng bạn đang gặp phải là sự thay thế quá trình, <(...)dường như không quan tâm đến việc lồng các parens trong đó.

Ví dụ - quy trình phụ + HEREDOC không hoạt động

$ cat <(fmt --width=10 <<FOO
(one)
(two
FOO
)
bash: bad substitution: no closing `)' in <(fmt --width=10 <<FOO
(one)
(two
FOO
)
$

Thoát khỏi parens dường như để xoa dịu nó, một chút:

Ví dụ - thoát parens

$ cat <(fmt --width=10 <<FOO                 
\(one\)
\(two
FOO
)
\(one\)
\(two

Nhưng không thực sự cung cấp cho bạn những gì bạn muốn. Làm cho các parens cân bằng dường như cũng xoa dịu nó:

Ví dụ - cân bằng parens

$ cat <(fmt --width=10 <<FOO
(one)
(two)
FOO
)
(one)
(two)

Bất cứ khi nào tôi có các chuỗi phức tạp, chẳng hạn như điều này xảy ra với Bash, tôi hầu như sẽ luôn xây dựng chúng trước, lưu trữ chúng trong một biến và sau đó sử dụng chúng thông qua biến, thay vì thử và tạo ra một lớp lót phức tạp cuối cùng trở thành mong manh.

Ví dụ - sử dụng biến

$ var=$(fmt --width=10 <<FOO
(one)
(two
FOO
)

Sau đó để in nó:

$ echo "$var"
(one)
(two

Người giới thiệu


3

Đây chỉ là một cách giải quyết. Ống fmtđể catthay vì sử dụng thay thế tiến trình

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
Tôi đã thử "cách giải quyết" của bạn và nó sẽ hiệu quả với tôi. Cảm ơn. Nhưng tôi vẫn muốn hiểu tại sao sự kết hợp của tôi với một tài liệu TẠI ĐÂY được lồng trong một sự thay thế quá trình không hoạt động. Bạn đã có câu trả lời?
Tim Friske

@TimFriske, tôi sẽ phải trì hoãn một trong những bashphù thủy trên trang web này. Kiến thức của tôi về nội bộ trình phân tích cú pháp bash bị giới hạn để nói ít nhất
iruvar

2

Đây là một câu hỏi cũ và khi bạn nhận ra rằng đây là một ví dụ giả định (và do đó, giải pháp chính xác là sử dụng cat |hoặc thực sự, không có gì cattrong trường hợp này), tôi sẽ chỉ đăng câu trả lời của mình cho trường hợp chung. Tôi sẽ giải quyết nó bằng cách đặt nó vào một chức năng và sử dụng nó thay thế.

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
}

và sau đó sử dụng nó

cat <(fmt-func)

Cảm ơn bạn! Chính xác những gì tôi đang tìm kiếm.
piarston
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.