Gelen bu soru birisi bir kullanırken sorun raporları burada belgeyi içinde bir alıntı sınırlayıcı kelime ile $(...)komut ikamesi bir ters eğik çizgi, \belge tetikleyiciler içinde bir satırın sonundaki newline-birleştiren çizgi devamında , burada aynı süre belgelemek dışında beklendiği gibi komut ikamesi işleri .
İşte basitleştirilmiş bir örnek belge:
cat <<'EOT'
abc ` def
ghi \
jkl
EOT
Bu, bir satırın sonunda bir ters tırnak ve bir ters eğik çizgi içerir. Sınırlayıcı belirtilir, bu nedenle vücudun içinde herhangi bir genişleme meydana gelmez. Tüm Bourne-aliklerinde bu çıktıları kelimesi kelimesine bulabilirim. Aynı belgeyi aşağıdaki gibi bir komut yerine koyarsam:
x=$(cat <<'EOT'
abc ` def
ghi \
jkl
EOT
)
echo "$x"
artık aynı şekilde davranmazlar:
dash,ash,zsh,ksh93, BusyBoxash,mkshve SunOS 5.10 POSIXshhepsi daha önce olduğu gibi dökümanının birebir içeriğini verir.- Bash 3.2, benzersiz bir backtick için bir sözdizimi hatası verir. Eşleştirilen ters tırnaklarla, içeriği bir komut olarak çalıştırmaya çalışır.
- Bash 4.3, "ghi" ve "jkl" değerlerini tek bir satıra daraltır, ancak hata içermez.
--posixSeçenek bu etkilemez. Kusalananda banapdkshaynı şekilde davrandığını söylüyor (teşekkürler!) .
Orijinal soruda, bunun Bash ayrıştırıcısında bir hata olduğunu söyledim. Bu mu? [Güncelleme: evet ] Bulabileceğim POSIX'ten (tümü Kabuk Komut Dili tanımından) ilgili metin:
- §2.6.3 Komut Değiştirme :
$ (Komut) formuyla, eşleşen kapanış parantezine açık parantezin ardından gelen tüm karakterler komutu oluşturur. Herhangi geçerli kabuk komut dosyası için kullanılabilir komutu yalnızca belirtilmemiş sonuçlar üretir yönlendirmeler oluşan bir senaryo dışında.
- §2.7.4 Burada-Belge :
Herhangi bir bölümü ise kelimenin alıntı, ayırıcı üzerindeki alıntı çıkarılmasını gerçekleştirerek kurulacaktır kelime ve burada-belge satırları, genişletilmiş edilmeyecektir.
- §2.2.1 Kaçış Karakteri (Ters Eğik Çizgi) :
<newline> <ters eğik çizgiyi> takip ederse, kabuk bunu satır devamı olarak yorumlayacaktır. Giriş, belirteçlere bölünmeden önce <ters eğik çizgi> ve <yeni satır> kaldırılacaktır.
- §2.3 Jeton Tanıma :
Bir io_here belirteci dilbilgisi tarafından tanındığında (bkz. Kabuk Dilbilgisi ), bir sonraki NEWLINE belirtecinin hemen ardından gelen bir veya daha fazla satır , bir veya daha fazla burada bulunan belgenin gövdesini oluşturur ve Here- kurallarına göre ayrıştırılır. Belge .
Bir io_burayı işlemediğinde , kabuk, girişindeki bir sonraki karaktere aşağıdaki ilk uygulanabilir kuralı uygulayarak girdisini belirteçlere bölmelidir . ...
...
- Geçerli karakter <ters eğik çizgi>, tek tırnak veya çift tırnak işareti içeriyorsa ve tırnak içine alınmamışsa, tırnak içine alınan metnin sonuna kadar sonraki karakterler için tırnak işaretini etkiler. Alıntı için kurallar açıklanmaktadır teklif . Jeton tanıma sırasında hiçbir ikame gerçekleştirilmeyecek ve sonuç belirteci, girişte görünen (<newline> katılma hariç), değiştirilmemiş, gömülü veya ekli tırnak işaretleri veya ikame operatörleri dahil olmak üzere, ve son arasındaki karakterleri içermelidir. alıntılanan metnin.
Benim yorumum $(, sonlandırmaya kadar olan tüm karakterlerin )kabuk betiğini, kelimesi kelimesine; burada belge görünür, bu nedenle sıradan belirleme yerine burada belge işleme gerçekleşir; buradaki belgenin alıntılanmış bir sınırlayıcısı vardır, yani içeriği kelimesi kelimesine işlenir; ve kaçış karakteri asla içine girmez. Ancak bu durumun ele alınmadığına ve her iki davranışa da izin verildiğine dair bir argüman görebiliyorum. Bir yerde de alakalı metnin bazılarını atlamış olabilirim.
- Bu durum başka yerlerde daha açık hale getirildi mi?
- Taşınabilir bir script neye güvenebilmelidir (teoride)?
- Bu kabuklardan herhangi birinin (Bash 3.2 / Bash 4.3 / diğer herkes) verdiği özel tedavi standart tarafından zorunlu mu? Yasak? İzin verilen?
echo "$x", ancak değişken çalışmalarını incelemek için herhangi bir yol. O satırı dibine düzenledim.
$(...)bu çıktı ne olursa olsun onun yerine geçer ... Şimdi, örneğin bir alt kabukta (in bash) komutu çalıştırdığınızda beklenen sonucu verir. Yalnızca komut yerine koymaya dönüştürüldüğünde "ghi" ve "jkl" kelimelerini daraltır. Yani bu bir böcek imo