Neden “do” yu “ile” aynı çizgiye yerleştirmem gerekiyor?


28

1. Özet

Anlamıyorum, neden E010 bazhate kuralına ihtiyacım var ?


2. Ayrıntılar

Dosyaları sıralamak için bashate kullanıyorum .sh. E010 kuralı:

yapmak aynı satırda değil için

for bashate:

  • Doğru:

    #!/bin/bash
    for f in bash/*.sh; do
        sashacommand "$f"
    done
  • Hata:

    #!/bin/bash
    for f in bash/*.sh
        do sashacommand "$f"
    done

Herhangi bir geçerli tartışma var mı, neden ihtiyacım var forve doaynı satırda?


3. yararlı değil

Soruma cevap bulamıyorum:

  1. Google
  2. En iyi kodlama uygulamaları hakkında makaleler ( örnek )
  3. temel belgeler . Ben sadece buluyorum:

    Kontrol bloklarında olayların tutarlı kalmasına yardımcı olan bir dizi kural. Bunları devam ettiren uzun çizgilerde görmezden gelinir, çünkü bunun çözülmesi bir tür “ilginç”


3
Girintisi dokesinlikle biraz sıradışı, ancak for ... \ndo\n<indent>body...son derece yaygın ve hatta bundan daha fazlasını tahmin ediyorum for ... ; do. Bundan da şikayet ediyor mu?
Michael Homer

20
bashatebir stil denetleyicisi. Stiller doğası gereği özneldir. Kestiği sanatsal tarzı sevmiyorsanız, kullanmayın. Bunun yerine shellcheck gibi bir sözdizimi / hata denetleyicisi düşünmelisiniz .
meuh

@meuh, teşekkürler, ben zaten ShellCheck kullanıyorum. benim sorum: E010- Sadece stil kuralı ya ihtiyacım bazı durumlarda için ve bunu sadece stil nedenlerle aynı çizgide.
Саша Черных

10
İçin bir sözdizimsel yükümlülük asla yoktur için ve yapmak kabuğunda aynı satırda.
meuh

1
@ Саша Черных Sıradışı olan, girintili olmayan, tek başına girintili değildir do. Açılış ayracını girin ifve C gibi bir dilde aynı satırda kod eklemek gibi. Python izin veriyorsa bir başka örnek :bir ifgirintiyi bir sonraki satıra koymak ve aynı satırda kod eklemek olacaktır. Vücuttaki ek çizgilerle onu farklılaştıracak.
JoL,

Yanıtlar:


60

Sözdizimsel olarak, aşağıdaki iki kod parçacığı doğru ve eşdeğerdir:

for f in bash/*.sh; do
    sashacommand "$f"
done
for f in bash/*.sh
    do sashacommand "$f"
done

İkinci bir olabilir , muhtemelen olarak okumak daha olduğu söylenebilir dohafif döngü gövdesinde komutu üstünü örter. Döngü birden fazla komut içeriyorsa ve bir sonraki komut yeni bir satırdaysa, şaşırtmaca daha fazla vurgulanır:

for f in *
    do cmd1
    cmd2
done

... ancak bunu bir "hata" olarak işaretlemek, IMHO'nun nesnel bir gerçeklikten ziyade kişisel görüşünü ifade eder.

Genel olarak, neredeyse her ;şey bir newline ile değiştirilebilir. Her ikisi de ;ve newline komut sonlandırıcılar. do"burada yapılması gerekenleri izler (bu fordöngüde)" anlamına gelen bir anahtar kelimedir .

for f in *; do ...; done

aynıdır

for f in *
do
   ...
done

ve benzeri

for f in *; do
   ...
done

Üst üste kullanılmasının nedeni okunabilirlik ve yerel / kişisel tarz sözleşmeleridir.


Kişisel görüş:

Çok uzun olan döngü başlıklarında do, olduğu gibi yeni bir satır koymak mantıklı gelebilir .

for i in animals people houses thoughts basketballs bees
do
    ...
done

veya

for i in        \
    animals     \
    people      \
    houses      \
    thoughts    \
    basketballs \
    bees
do
    ...
done

Aynı thenbir ifaçıklama için de geçerli.

Ancak yine, bu kişinin kişisel stil tercihlerine veya bir takımın / projesinin kullandığı kodlama stiline bağlıdır.


“Çok uzun olan döngü başlıklarında, yeni bir satıra koymak mantıklı olabilir” diyorsunuz. Bunun için bir sebep söyleyebilir misiniz? Başlığın takip etmesi gerektiği göz önüne alındığında, dobir sonraki satıra koymanın okunabilirliğe neden yardımcı olacağına dair bir neden görmüyorum.
Konrad Rudolph

3
@KonradRudolph Terminalim 80 karakter genişliğindedir. Eğer liste tamamlanırsa, devam eden bir dizi satır oluşturacağım (son örneğimde olduğu gibi), neredeyse tamamlanmışsa, do(veya then) 'yı kendi başına bir satıra (sondan ikinci örneğe olduğu gibi) koyacağım . Bunların hepsi kişisel tercihlerle ilgilidir. Aşırı uzun çizgileri sevmiyorum, kısmen terminalim "sadece" 80 karakter genişliğinde ve kısmen düzensiz göründüğü için. Ayrıca hatalardan dolayı çok uzun satırları ayrıştırmayı zor buluyorum.
Kusalananda

1
Bunun bir fikir olduğunu belirtmeye devam etmek gereksiz görünüyor. bashate bir stil rehberidir, bu yüzden doğal olarak düşünceye dayanır.
Barmar

4
@Barmar, buradaki sorunun "ihtiyaç" ve "kural" gibi ifadeler kullandığını ve bazhate benioku öğesinin doayrı bir satırda "hata" olduğunu söylediğini unutmayın . O kadar olanlar, daha doğrusu sıkı ifadelerdir gelmez oldukça tersine, sözde "kuralı" aslında sadece öznel bir görüşü, yani işaret etmek değerinde görünüyor.
ilkkachu

2
@mtraceur Doğru, kişisel tercihleri ​​sorgulamıyorum. Ancak, teklif ettiğiniz okunabilirlik sütun sınırının koda uygulanmadığını unutmayın. Sadece nesir için geçerlidir. Göz hareketi kod okuma için temelde farklıdır, bu nedenle bu çalışmalardan elde edilen kanıtlar burada geçerli değildir. Ve artık gerekçe olarak geçerli olmayan tarihsel nedenleri kullanmaya gelince, 8.3 dosya ismini de kullandık.
Konrad Rudolph

28

Sayfanın üst kısmında ne yazdığını not edin:

bashate: bash scriptleri için pep8 eşdeğeri

PEP8 Python Kodu için Stil Kılavuzu. Python millet çoğu zaman stil sorunlarını çok ciddiye alıyor gibi görünmekle birlikte [kaynak belirtilmeli] , bu sadece bir rehber. Hem doçizgiyi aynı çizgiye koymak, hem forde kendi çizgisine koymak için başa çıkabildik .

{Bir ifveya whileblok (veya benzeri) başlatırken C kodunu nereye koyacağınızla aynı tartışma .


Belgelerde aşağıdaki birkaç satır, başka ilginç bir kural var:

E020: İşlev bildirimi biçiminde değil ^function name {$

Buradaki noktanın, bu stil rehberinin yazarının function, okuyucunun işlev bildirimini tanıması için anahtar kelimenin kullanılmasının gerekli olduğunu düşündüğü olduğunu farz ediyorum . Ancak, bir işlevi tanımlamanın standart olmayanfunction foo bir yoludur: standart yoldur . İkisi arasındaki tek fark (Bash cinsinden), diğerinin Debian veya Ubuntu'daki gibi standart bir kabuğa taşımayı zorlaştırmasıdır .foo()/bin/sh

Bu yüzden, bu tarz tarla kılavuzlarını bir ya da üç tane tuzla alıp kendinize en iyi tarzın ne olduğuna karar vermenizi öneririm. İyi bir stil denetleyicisi bazı çeklerin devre dışı bırakılmasına izin verir (bazhate bashate -i E010,E011bu iki çekimi göz ardı etmelidir .) Mükemmel bir stil denetleyici testleri burada, örneğin E020'nin tersini kontrol etmek için değiştirmenize izin verir.


12

TL; DR: Buna gerek yok. Bu sadece bir erkeğin görüşü.

Diğerleri forgibi onlarca yıldır böyle döngüler yazıyorum :

for F in arg1 arg2 arg*
do
    somecommand "$F"
done

Bu düzen do ... done, C benzeri dillerde kıvrık parantezler gibi döngü gövdesini çevreleyen gerçeğini vurgular ve yeni satırların döngü yapısının bileşenlerini ayırmasına izin verir.

Elbette, kıvrık kaşlı ayraçları da nereye yerleştireceğinizle ilgili dini savaşlar var, bu yüzden jürinin hala bunun dışında olduğunu söyleyebilirsin. IMHO, bu açıkça çalışmak için tasarlanmıştı; Bourne eşleşmiş sınırlayıcılara düşkündü, bkz. if ... fi, case ... esacve daha kısa sürümde bir noktalı virgül gereksinimi, onu orijinal tasarımdan daha kısa yaptığınızı ortaya koyuyor. Bunda yanlış bir şey yok; teknoloji gelişmeleri ve bir zamanlar iyi bir fikir gibi görünen pek çok şey şimdi kaşlarını çattı goto. Ancak tüm kabuk komut dosyası oluşturma topluluğu bashateyazarların tercihlerini kabul edene kadar bir şey yapmanıza gerek yoktur.


3
fiKarşılık geldiğini ifve esacvb Algol 68. Bir tek nedeni gelen forkatlama 's dosona değildir odyani od, mevcut bir standart yardımcı adıdır. Bkz en.wikipedia.org/wiki/ALGOL_68C#Algol_68C_and_Unix
Kusalananda

1
Doğru ve anahtar kelime ile sınırlandırılmış bloklar, Algol ailesinin diğer dillerinde, Pascal (kullanılanlar begin ... endvb. Dahil ) de kullanılmıştır.
alexis,

2
odBununla ilgili hikayeyi duymamıştım , bu komik ... (Her ne kadar, neden sadece döngülerle bitmiyorsunuz rof?)
alexis

2
@alexis Kusalananda'nın dediği gibi Algol 68'den geliyor, kilit nokta bu. Orijinal Bourne kabuğunun yaratıcısı Stephen Bourne, o dilden çok etkilendi ve bu yüzden bu sözdizimine saplandı. C de yazarken bile Bourne kabuğu için kaynak koduna bakınız: minnie.tuhs.org//cgi-bin/utree.pl?file=V7/usr/src/cmd/sh/mac.h Oh, ve yol BEGINve ENDorada da tanımlanır.
Sergiy Kolodyazhnyy

1
Bu biçimlendirme tarzının tamamı aynı zamanda Algol 68'den geliyor. Onun FORve DOaynı zamanda bütün döngü kolayca tek bir satırda uyabilecek durumlar hariç Kongre tarafından ayrı çizgiler, üzerinde olurdu.
reinierpost

3

Henüz kimsenin bu geçerli ve taşınabilir sözdiziminden bahsetmediğine şaşırdım:

set alfa bravo charlie
for q do
  echo "$q"
done

Dikkatli bir şekilde dikkat edin forve donoktalı virgül olmadan aynı satırda. Sonuç:

alfa
bravo
charlie

Bu cevabın bir sözünü eklemek için bu cevabı onaylıyorum (ancak bazı durumlarda temiz ve taşınabilir kabuk kodu için kritik) sözdizimi, ancak bunun insanlara konumsal parametreleri gizlediğini açıkça belirtmekte fayda var. tek "gerçekten taşınabilir (tm)" form, ayrı satırlarda for qve doayrı satırlardadır (bu örnekteki form, birkaç yıl önce orijinal Almquish kabuğundaki ( ash) desteklenmiyordu: in-ulm.de/~mascheck/various/ bourne_args / # endnote )
mtraceur

Bu cevap örnek benim için çalışıyor iken, OP'ın söz konusu örneğe uygulayarak yapar değil iş.
Scribblemacher

3

Burada birkaç iyi cevap. Her zaman bir tuz taneleri ile stil rehberleri alın ve IMHO ile deneyim, stil konusunda aşırı dogmaya maruz kalan herhangi bir topluluk hakkında her zamankinden biraz orta derecede endişeli olun. Neredeyse son nokta attığım ve son T'yi geçtiğinde yazılımın işe yarayacağına inanıyor gibiydiler. Bazen böcekleri gidermek için mükemmel bir tarzdan daha fazlasını gerektirir ...

Kabuk öğrenmeye başladığımda, çoğu komut dosyası ve tutuş orada satır içi noktalı virgül biçimini kullandı

for i in "$@"; do
    stuff
done

ama deneyimsiz olduğum için, farkına varmakta zorlandım; ve - her ikisi de sözdizimsel doğruluğu onaylamak için gereklidir. Bu yüzden bir sonraki satırda tek başıma yapmayı tercih ettim. Bunu artık yapmıyorum (amaçlanan)

Ayrıca 'while' komutu küçük bir numara için mükemmel bir aday:

while prep1; prep2; condition; do
    stuff
done

ancak hazırlık komutları biraz hantal olduğunda ve / veya durum karmaşık olduğunda,

while
    prep1
    prep2
    condition
do
    stuff
done

ve ardından do 'yu'; 'do' 'olarak eklemek olumlu bir şekilde fugly.

Bundan daha da yoğunlaşabilirsiniz:

while
    if con1; then
      cond2
    elif cond3; then
      cond4
    elif cond5; then
      cond6
    else
      cond7
    fi
do
    stuff
done

çünkü her ifade bir ifadedir. Her iki stilin fırsatçı olarak nasıl kullanıldığına dikkat edin. Temiz tutun ve oldukça okunabilir. Stil veya "yerden tasarruf" adına sıkıştırın ya da çarpıtın ve korkunç bir karışıklık olur.

Yani! Genel olarak kabuk betiklerinin barok stilleri göz önüne alındığında, netliği ve anlamlı sembollere kolay görsel erişimi arttırmayı amaçlayan herhangi bir şey her zaman iyi bir şeydir.

'Do' komutunun satırına yazıldığı biçim, küçük bir komutunuz olduğunda tatlıdır - 'do' komutunu görsel olarak gizli bulmuyorum ya da iç komut gerçekten gizlenmiş değil:

for i in whatever
  do stuff
done

Bunu bakmak oldukça keyifli buluyorum ve süre, eğer ve durumla benzerleri var:

while condition
  do stuff
end

if condition
  then stuff1
  else stuff2
fi

case $blah in
  a) stuff1;;
  b) stuff2;;
  c) stuff3;;
  *) stuffInfinity;;
esac

Netlik ve genel düzen, Codd * 'in sizden istediği şeydir.

* Edgar F. Codd, ilişkisel veritabanı teorisinin babası.


1
Daha önce hiç whilebir ifşartla görmedim . Güzel!
Joe
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.