Heredoc için çok satırlı sözdizimi; bu taşınabilir mi?


132

Bu sözdizimine aşinayım:

cmd1 << EOF | cmd2
text
EOF

ama bash'ın yazmama izin verdiğini yeni keşfettim:

cmd1 << EOF |
text
EOF
cmd2

(yorum cmd1'e girdi olarak kullanılır ve cmd1'in çıktısı cmd2'ye aktarılır). Bu çok garip bir sözdizimi gibi görünüyor. Taşınabilir mi?


Ben birden fazla satır halinde ayrılarak bunun iyi bir yol bulmaya geldim: big-long-command1 with lots of args << EOF | big-long-command2 with lots of args. "Garip sözdizimi" en iyi yol gibi görünüyor.
PaulC

Bunun uygun kullanım durumlarından biri, boşlukla ayrılmış bir tabloyu sekmeyle ayrılmış bir tabloyu Google E-Tablolar'a yapıştırabilmeniz için sekmeyle ayrılmış bir tabloyu dönüştürmeye çalıştığınız zamandır. Geçici bir dosya oluşturmanız gerekmeyecek.
Sridhar Sarnobat

İlki benim için z-shell'de çalışmadı. İkincisini sevmiyorum çünkü | komuttan, kabuk boru hatlarının deyimini (?) kaybetti.
Sridhar Sarnobat

Yanıtlar:


104

Evet, POSIX standardı buna izin verir. 2008 versiyonuna göre:

Buradaki belge, bir sonrakinden sonra başlayan <newline>ve aralarında karakter <newline>olmadan yalnızca sınırlayıcı ve a'yı içeren bir satır olana kadar devam eden tek bir kelime olarak ele alınacaktır <blank>. Sonra bir sonraki buradaki belge başlar, eğer varsa.

Ve aynı satırda birden çok "buradaki belge" örneğini içerir:

cat <<eof1; cat <<eof2
Hi,
eof1
Helene.
eof2

Dolayısıyla, yönlendirmeler veya kanallar yapmakta sorun yoktur. Örneğiniz şuna benzer:

cat file |
cmd

Ve kabuk dilbilgisi (bağlantılı sayfanın ilerleyen kısımlarında) şu tanımları içerir:

pipe_sequence    :                             command
                 | pipe_sequence '|' linebreak command

newline_list     :              NEWLINE
                 | newline_list NEWLINE
                 ;
linebreak        : newline_list
                 | /* empty */

Dolayısıyla, bir boru sembolünün ardından bir hat sonu gelebilir ve yine de bir boru hattının parçası olarak kabul edilebilir.


26

Evet, POSIX kabuk gramerinde. Aynı komut için birden fazla here-doc'a da sahip olabilirsiniz (diğer bazı örnekler iki catçağrı kullanır , ancak bu da işe yarar ):

cat <<EOF1 <<EOF2
first here-doc
EOF1
second here-doc
EOF2

Bu yapmacıktır (stdin için 2 here-docs kullanılarak), ancak farklı dosya tanımlayıcıları için girdi sağlamayı düşünürseniz, bu hemen anlamlıdır.

Ayrıca tamamen bırakmacat olasılığı da var . Neden buradaki belgeyi doğrudan şu kullanıcılara sunmuyorsunuz cmd:

cmd << EOF
input
here
EOF

`` `` cat << EOF1 << EOF2 birinci burada-doc EOF1 ikinci burada-doc EOF2 `` Yukarıdakiler çalışmıyor.
user1424739

@ user1424739 Mevcut zsh ve bash'da çalışıyor. Ash ve ksh93 burada yalnızca ikinci doc çıktı gibi görünüyor.
Jens

Neden olumsuz oy? Yanlış bir şey varsa, lütfen bana çare bulma fırsatı verin.
Jens

Bu, kullanırken oldukça tatlı sudo tee /etc/securefile.conf <<EOF.
dragon788

Hangi bash sürümünde çalışıyor? Bash 4.4.19'u (ubuntu 18.04.02'de) ve bash 5.0'ı (docker görüntüsü) kullanarak, burada yalnızca ikinci olanı aldım-doc. Ya da belki belirli bir seçenek var mı?
huelbois

17

Hmm, sanırım evet, POSIX modundaki bash testine göre:

$ bash --posix
$ cat <<EOF |
> ahoj
> nazdar
> EOF
> sed 's/a/b/'
bhoj
nbzdar

Küçük bir not daha: Kapanıştan sonra boşluk bırakmayın EOF. Komut tuhaf davranacak ve neyin yanlış olduğunu merak edeceksiniz
Sridhar Sarnobat

2
Bash'ı POSIX modunda çalıştırmak bazı uzantıları kapatır , ancak hiçbir şekilde neredeyse hepsini bile kapatmaz . Bu nedenle, bu cevap POSIX'in izin verdiği şeyler açısından doğru olsa da, muhakemesi bunu çok etkili bir şekilde desteklemiyor.
Charles Duffy

3

Merhaba, örneğin şunu kontrol et

#!/bin/sh
( base32 -d | base64 -d )<<ENDOFTEXT
KNDWW42DNNSHS5ZXPJCG4MSVM5MVQVT2JFCTK3DELBFDCY2IIJYGE2JUJNHWS22LINVHQMCMNVFD
CWJQIIZVUV2JOVNEOVJLINTW6PIK
ENDOFTEXT

Saygılarımızla

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.