Bir ayraç komut grubunun neden POSIX Kabuk Dilbilgisi'ndeki açılış ayracı sonrasında boşluklara ihtiyacı var?


10

TL; DR : POSIX destek grubunun neden {ayrılmış sözcükten sonra boşluklara ihtiyacı var, ancak alt kabuk ayrılmış sözcükten sonra boşluk gerektirmiyor (?

POSIX kabuk dilbilgisi küme grubu ve alt kabuğu aşağıdaki gibi tanımlar

brace_group      : Lbrace compound_list Rbrace

subshell         : '(' compound_list ')'

Şimdi, kelimenin tam anlamıyla okursak, boşluklar önemlidir. Bu, boşluk ayırıcı açma ve kapama ayracı ve parantezin olduğu gibi olması gerektiği anlamına gelir.

{ echo hello world; }

( echo hello world )

Bu ayrıca Bileşik Komut tanımlarıyla da uyumlu olacaktır :

Bu bileşik komutların her birinin başında ayrılmış bir sözcük ya da denetim işleci ve sonunda karşılık gelen bir sonlandırıcı ayrılmış sözcüğü ya da işleci vardır.

Bununla birlikte, mantıklı olmayan şey neden (list)ve ( list )iyi çalışıyor (bu boşluktan sonra (gerekli değildir), ancak küme ayracı genişlemesinin önde gelen bir alana sahip olması gerekir, yani {echo hello;}işe yaramaz.

Tabii ki kabuk kelime olarak muamele edilen ayrılmış kelime, daha sonra alan bölünmesi kavramına uyum sağlamak için bir boşluğa ihtiyaç duyulması anlamlıdır , ancak tanımın kendisi boşluklardan bahsetmez. Dahası, eğer {ve (onlar bu amaçlı sözcükler sonra boşluk karakteri açısından farklı muamele ediyoruz neden bileşik komuta POSIX tanımı, hem kabul saklıdır kelimelerdir? Şimdi, ksh (1) manuel şunları ifade eder:

Karakter dizisi olan kelimeler, sıralanmamış boşluk karakterleri (boşluk, sekme ve yeni satır) veya meta karakterler (<,>, |,;, &, (ve)) ile sınırlandırılır

Başka bir deyişle, ksh'ın (ilk sözcüğün bir komut veya değişken ataması olacağı sözcük sınırlayıcı olarak tanıması mantıklıdır . Ancak POSIX, (meta karakter olarak bahsedilmiyor . POSIX dilbilgisi ile ilgili olarak bulduğum tek olası açıklama {, bir "jeton" olarak kabul edilir, burada bir olarak (listelenmez.

/* These are reserved words, not operator tokens, and are
   recognized when reserved words are recognized. */


%token  Lbrace    Rbrace    Bang
/*      '{'       '}'       '!'   */

Peki bu tutarsızlığın kesin mantığı ne olurdu?

Kabul Edilen Cevap Notları:

  • Soruma doğrudan cevap veren standardın kendisinden q uote sağladığı için kabul edilen onay işaretini Isaac'in cevabına taşıdık :

    Örneğin, '(' ve ')' kontrol işleçleridir, bu nedenle <space>(listede) gerekli değildir. Ancak, '{' ve '}' {list;} içindeki ayrılmış kelimelerdir, bu durumda öncü <space>ve <semicolon>gereklidir.

  • Kusalananda'nın cevabını kabul etmek . Kusalananda'nın cevabı, çoğunlukla gayri resmi ve sezgisel açıdan ihtiyaç duyduğum şeye; işaret {ayrılmış bir kelime ve (operatör. Michael Homer ayrıca, Bileşik Komuta tanımının belirttiği (vurgu eklendi) yorumlarda da aynı şeyi kaydetti:

    Bu bileşik komutların her birinin başında ayrılmış bir sözcük veya denetim işleci vardır

  • {Kabuk Dilbilgisine benzer forveya whilelistelenen ayrılmış sözcük olarak tanımlanır (sorudaki son kod bloğuna bakın)

  • Bölüm 2.9 şunları belirtir (vurgu eklenmiştir):

    Özellikle gösterimler, s'nin gerekli olmayacağı bazı yerlerde jetonlar arasındaki boşluğu içerir (jetonlardan biri bir operatör olduğunda).<blank>

  • Standart açıkça (bir operatör olarak tanımlanmamış olsa da, operatör (olarak adlandırılır; özellikle, bölüm 2.9.2 diyor

    Eğer boru hattı ayrılmış kelime ile başlıyorsa! ve komut1 bir alt kabuk komutudur, uygulama (komut1'in başındaki işleç! ile bir veya daha fazla karakter arasında ayrılmalıdır.

  • Dijital Travma ile Yığın Taşması Sorusu, Ayrılmış Kelimelerle ilgili Bölüm 2.4'e dikkat çekiyor:

    Bu tanıma yalnızca karakterlerin hiçbiri alıntılanmadığında ve kelime şu şekilde kullanıldığında gerçekleşir:

    -Komutun ilk kelimesi

  • Kusalananda'nın cevabında belirtildiği gibi "POSIX dilbilgisinde gösterilen boşluklar, kabuk girdi verilerinde bulunması gereken boşluklar değil, sadece dilbilgisinin kendisini göstermenin bir yoludur. Parantezlerin, boşluklarla çevrelenmeleri gerekiyor " Yorumlarda Michael Homer tarafından belirtildiği gibi :" Alanlar kendi başlarına önemli olsaydı, prodüksiyonda listelenmeleri gerekirdi "

Dava kapandı.


3
Alanlar kendi başlarına önemli olsaydı, prodüksiyonda listelenmeleri gerekirdi.
Michael Homer

2
"Ayrıca, eğer, {ve (birleşik komutun POSIX hem olarak ayrılmış kelimeler" karş "Bu bileşik komutların her birinin başında ayrılmış bir sözcük ya da kontrol operatörü var ".
Michael Homer

2
@SergiyKolodyazhnyy Alan önemliyse, dilbilgisinin açık bir boşluk karakteri ( ' ') içermesi gerektiği anlamına geldiğine inanıyorum . Bunun yerine, boşluklar hangi tokenlerin kelimeler olduğu anlamına gelir.
Kusalananda

2
Token sınıfının şartname tanımı ... en azından söylemek zor. Tüm dilbilgisi oldukça korkunçtur ve spec, metin içindeki nesir nesnelerini (bazen örtülü olarak!), Dilbilgisinden önceki nesir kurallarında ve dilbilgisinin kendisinde tanımlayan şeyleri karıştırır. Cevabı zaten bilmiyorsanız ve geriye doğru çalışıyorsanız oldukça anlaşılmaz. Sözcüksel kuralların tümü, belirtecin ne içerdiğini tanımlamak yerine, yeni bir belirteç başlatan tarafından geriye doğru tanımlanır. Bu sadece bir karmaşa.
Michael Homer

1
@ Resmi dilbilgisi içinde bir üretim (veya üretim kuralı), başka bir şeyden nasıl bir şeyler üretebileceğinizi açıklar. Bkz. En.wikipedia.org/wiki/Production_%28computer_science%29 Yani command : simple_command | compound_command | compound_command redirect_list | function_definition ;bir komuta sahip olabileceğinizi söyleyen bir prodüksiyon, basit bir komut, birleşik komut veya yeniden yönlendirmeli bir bileşik komut veya bir fonksiyon tanımı olabilir.
muru

Yanıtlar:


6

Bu, kabuğun çizgileri jetonlara ayırma biçiminin bir sınırlamasıdır.

Kabuk , giriş dosyasındaki satırları okur ve Bölüm 2'ye göre "Kabuk Tanıtımı" , bunları bir sözcüğe veya bir işleve dönüştürür :

  1. Kabuk girdiyi jetonlara böler: kelimeler ve işleçler

{ayrılmış bir kelimedir

Bazı kelimeler ayrılmış kelimelerdir

Ayrılmış kelimeler, kabuğa özel bir anlam ifade eden kelimelerdir. Aşağıdaki kelimeler ayrılmış kelimeler olarak kabul edilecektir:

! { } case do done elif else esac fi for if in then until while

Kelime olarak kabul edilecek Kelimeler, olmalıdır ayrılmış .

Ayrılmış kelimeler yalnızca sınırlandırıldığında tanınır ...

Çoğunlukla boşluklar (nokta 7) ve operatörler tarafından.

  1. Geçerli karakter sıralanmamış <boş> ise, önceki karakteri içeren herhangi bir simge sınırlanır ve geçerli karakter atılır.

(operatör

Operatörler kendi başlarına :

oysa operatörlerin kendileri sınırlayıcıdır.

Nerede "operatörleri" ya şunlardır :

3.260 Operatör

Kabuk komut dilinde, bir kontrol operatörü veya bir yönlendirme operatörü.

Yönlendirme operatörleri :

Yönlendirme İşleci

Kabuk komut dilinde, yeniden yönlendirme işlevi gerçekleştiren bir belirteç. Aşağıdaki sembollerden biridir:

<     >     >|     <<     >>     <&     >&     <<-     <>

Kontrol operatörleri :

3.113 Kontrol Operatörü

Kabuk komut dilinde, bir kontrol işlevi gerçekleştiren bir belirteç. Aşağıdaki sembollerden biridir:

&   &&   (   )   ;   ;;   newline   |   ||

Sonuç

Dolayısıyla, '(' ve ')' kontrol operatörleriyken, '{' '}' ayrılmış kelimelerdir.

Ve sorunuzun tam olarak aynı açıklaması spesifikasyonun içinde :

Örneğin, '(' ve ')' kontrol işleçleridir, böylece (listede) <boşluk> gerekmez. Ancak, '{' ve '}' {list;} içindeki ayrılmış kelimelerdir, bu durumda önde gelen <boşluk> ve <semikolon> gereklidir.

Bu tam olarak neden bir alanın (veya başka bir sınırlayıcının) a {.

Bu geçerlidir:

{ echo yes;}

Bu şekilde:

{(echo yes);}

Bu:

{(echo yes)}

Hatta bu bile:

{>/dev/tty echo yes;}

Son alıntı tam olarak yerinde! + 1'lendi. Şimdi soruyu ve cevaplarını gözden
geçirmem

13

Küme parantezleri ve parantez arasındaki fark ayraçları (ve bu vardır !) gibi, ayrılmış kelimelerdir for, if, thenparantez kontrol operatörleri ise vb. Kelimelerin boşlukla ayrılması gerekir.

Bu, tıpkı sahip olamayacağınız gibi

foriin*; do

sahip olamazsın

{somecommand;} >file

veya

if !somecommand; then

POSIX dilbilgisinde gösterilen boşluklar, kabuk giriş verilerinde bulunması gereken boşluklar değil, yalnızca dilbilgisinin kendisini göstermenin bir yoludur. Parantezlerin, boşlukla çevrelenmeleri gerektiğini ima eden ayrılmış kelimeler olduğu, ancak bir alt kabuğun parantezleri olmadığı gerçeğidir.


1
Eh, bu hemen hemen buna cevap veriyor gibi görünüyor ve görüyorum ki "Özellikle, gösterimler <boşluk> 'un gerekli olmadığı bazı yerlerde belirteçler arasındaki boşluğu içerir (belirteçlerden biri bir operatör olduğunda)". Tek bir soru: Standart nerede (operatör olarak tanımlanıyor ? En azından dilbilgisi bölümünde değil
Sergiy Kolodyazhnyy

@MichaelHomer Ah, "kontrol operatörü" gibi ;. Bunun için teşekkürler.
Kusalananda

Kontrol operatörleri, man sayfasının üst kısmında TANIMLAR altında listelenir. Her ikisinin de alt kabukları içermesi ()gibi kontrol operatörleri olarak bakabiliriz |. Ve { }mevcut kabukta çalışır ve bir alt kabuk içeremez.
glenn jackman

@Kusalananda Bulundu, bölüm 2.9.2: "Eğer boru hattı ayrılmış kelime ile başlıyorsa! Ve command1 bir alt kabuk komutuysa, uygulama (komut1'in başındaki operatör! İle bir veya daha fazla < boş> karakterler. Ayrılmış sözcüğün davranışı! hemen ardından (operatör belirtilmemiş. "Net bir tanım değil, standart buna (operatör diyor
Sergiy Kolodyazhnyy

@glennjackman Boru hatlarının alt kabuklar içerdiği doğru olsa da, bu uygun görünen tanım türü değildir. Standart ayrıca, bazı uygulamalarda boru hattının geçerli kabuk yürütme ortamında çalışmasının uygun olduğunu belirtiyor (ve standart olduğunu biliyorum, çünkü metni dün gördüm ve şimdi arıyorum). Beni çok az standartta yapar yukarıda yorumladı alıntı bulmak Ancak, öneri noktası yoktu çağrı değil açıkça olsa operatör bunu tanımlamak biri olarak
Sergiy Kolodyazhnyy
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.