Bash'in süreç ikamesi ile HERE-belgesi nasıl birleştirilir?


14

Bash sürüm 4.2.47 (1) -daha gibi bir HERE-dcoument gelen biçimlendirilmiş metin katenate çalıştığınızda:

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.

Aşağıdaki hatayı alıyorum:

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
)

Ayrıca BURADA belgeyi alıntılamak istemiyorum, yani yazmak <'FOOBAR', çünkü hala değişkenlerin yerine ikame edilmesini istiyorum.


catAramaya gerçekten ihtiyacınız var mı? Neden aramada bırakmıyorsunuz fmt?
iruvar

2
İtiraf etmeliyim ki bu örnek bir örnek. Gerçek ihtiyaçlarım bundan daha karmaşık.
Tim Friske

1
Değiştirdiğinizde olması ilginçtir (Evenile "(Even"çalışıyor. Aynı \(Even. Ayrıştırma hatası gibi görünüyor. Bash, bu dokümanı okuma bağlamında da kaşlı ayraçlar ararken hala bir bağlamda ve her iki bağlam da birbiriyle çelişiyor.
Raphael Ahrens

1
Bu bash, tesadüfen 4.3'te düzeltildi .
chepner

Yanıtlar:


7

İşlem ikamesi kabaca buna eşdeğerdir.

Örnek - proses ikamesi mekaniği

Adım # 1 - Bir fifo yapın, çıktı alın

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

Adım # 2 - fifoyu okuyun

$ 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 içinde ebeveynlerin kullanımı da iyi görünüyor:

Örnek - sadece FIFO kullanmak

Adım # 1 - FIFO'ya Çıktı

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

Adım # 2 - FIFO'nun İçeriğini Okuyun

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

Karşılaştığınız sorun, süreç ikamesinin, <(...)içindeki ebeveynlerin yuvalanmasını umursamadıklarıdır.

Örnek - işlem alt + HEREDOC çalışmıyor

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

Parens'ten kaçmak biraz sakinleşiyor gibi görünüyor:

Örnek - kaçan parens

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

Ama size gerçekten ne istediğinizi vermiyor. Parensleri dengede tutmak da onu yatıştırıyor gibi görünüyor:

Örnek - dengeleme parenleri

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

Bash ile mücadele etmek için böyle karmaşık dizelere sahip olduğumda, hemen hemen her zaman önce bunları bir değişkente saklayacağım ve sonra bunları değişken olan bir yolla kullanacağım. kırılgan.

Örnek - bir değişken kullanın

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

Sonra yazdırmak için:

$ echo "$var"
(one)
(two

Referanslar


3

Bu sadece bir çözüm. Boru fmtiçin catyerine işlem ikame kullanmanın

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
"Geçici çözümünüzü" denedim ve bu benim için işe yarar. Teşekkürler. Ama yine de neden bir proses ikamesi içine yerleştirilmiş bir HERE-belge kombinasyonumun işe yaramadığını anlamak istiyorum. Cevabın var mı?
Tim Friske

@ TimFriske, bunu bashbu sitedeki sihirbazlardan birine ertelemem gerekecek . Bash ayrıştırıcı iç
bilgim

2

Bu eski bir sorudur ve bunun tartışmalı bir örnek olduğunu (ve böylece doğru çözümün kullanmak olduğunu cat |veya aslında catbu durumda hayır olduğunu) fark ettiğiniz gibi , genel durum için cevabımı göndereceğim . Bunu bir fonksiyona koyarak ve onun yerine kullanarak çözerdim.

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
}

ve sonra onu kullan

cat <(fmt-func)

Teşekkür ederim! Tam aradığım şey.
piarston
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.