4 puan yazan GN⁺ 2024-12-09 | 1 yorum | WhatsApp'ta paylaş
  • Bu wiki, yalnızca uzun betikler değil, elle yazılmış ve hatta veri yapıları ile algoritmalar kullanan “gerçek” Shell programlarının bir listesini toplar
  • Ölçüt genel olarak 5K satır ve üzeri; otomatik üretilmiş betikler veya tekrarlı completion betikleri çekirdek örneklerin dışında bırakılır
  • Temsilî örnekler arasında ble.sh 87K satır, kalua yaklaşık 56K SLoC/satır, Relax-and-Recover 35K satır, nb 26K satır ve winetricks 22K satır yer alır; bunlar yaygın Shell betiği algısının çok ötesine geçer
  • Listede etkileşimli satır düzenleyici, OpenWRT eklentisi, Bash hata ayıklayıcı, TLS test aracı, Kubernetes uygulaması, yedekleme·kurtarma aracı, sertifika çıkarma aracı, kaynak izleyici gibi gerçek kullanım araçları geniş bir yelpazede yer alır
  • OSH “Wild” testi bir milyondan fazla satır Shell kodunu parse eder, ancak bunun büyük kısmı küçük programlar ve tekrarlı dağıtım paketi tanımları olduğundan büyük Shell programlarından ayrı değerlendirilir

“Büyük bir Shell programı” ne sayılır?

  • Buradaki “biggest”, yalnızca ham satır sayısından çok “substantial”, yani gerçek ölçek ve karmaşıklığı ifade eder
  • Kapsama alınanlar temelde elle yazılmış Shell betikleridir
    • autoconf’un ürettiği büyük betikler istisna tutulur
    • 70K satırlık coreutils betiği gibi otomatik üretimler, gerçek anlamda büyük Shell programı sayılmaz
  • Veri yapıları ve algoritmalar kullanan Shell programlarına özellikle önem verilir
    • bash-completion gelişmiştir, ancak Unix makinedeki her komut için görece basit fonksiyonlar içeren tekrarlı bir yapıya sahip olduğundan karşı örneğe daha yakındır
  • Kabaca eşik 5K satırın üzeridir
    • Tekrarlı olmayan en büyük Shell programları genelde 10K+ satır aralığındadır
    • 100K satırı aşan bir program henüz doğrulanmamıştır

En büyük Shell programı örnekleri

  • akinomyoga/ble.sh: toplam 87K satır, yorumlar hariç 63K LoC
    • Tamamen bash ile yazılmış, fish benzeri etkileşimli bir satır düzenleyicisidir
    • Ana dosya out/ble.sh 39K satır, yorumlar hariç 29K LoC; modül dosyalarıyla birlikte toplam 80K+ satıra ulaşır
    • Çok sayıda Japonca yorum içerir
    • bind -x ile terminalin raw byte’larını okur, birden fazla açık durum makinesiyle bunları doğrudan decode eder ve drawing buffer’ı koruyup günceller
    • timing ve “fibers” da içerir
    • Shell parser ile ilgili ayrıntılar issue 663 yorumunda yer alır ve Shell’de veri yapılarının en sofistike kullanımlarından biri olarak değerlendirilir
    • OSH üzerinde çalıştırma denemeleri vardır ve büyük kısmı parse edilir
    • İlk commit 2015’te 8K satır / 6K LoC idi; fiilî geliştirme ise 2013’te başladı
  • kalua: OpenWRT eklentisi; POSIX shell ile yazılmış yaklaşık 56K SLoC/satır
  • Relax-and-Recover: 35K satır, 24K LoC’lik bir yedekleme·kurtarma aracı
    • İlk git commit’i Mart 2009’da yapıldı ve o sırada 4K satır / 3K LoC idi
  • xwmx/nb: nb’nin kendisi 26K satır, 22K LoC’lik bash kodudur
    • bats testleri bash olarak sayılırsa ek 91K satır, 61K LoC daha vardır
    • İlk commit 2014’te yapıldı; aktif commit geçmişi 2016 başlarında başladı
  • vegardit/bash-funk: toplam 27K satır, 24K LoC’lik bir Bash kütüphanesi
    • İlk commit Mayıs 2017’de, o sırada 10K satır / 8K LoC idi
  • winetricks: 22K satırlık bir Shell betiğidir ve Wine altında çeşitli Windows programlarını kurar
  • drwetter/testssl.sh: tek dosyada 21K satırlık bash içerir
    • Elle yazılmış görünüyor
    • 2006’da birkaç openssl komutuyla başladı
    • Parse sırasında issue #606’ya takılıyor
  • rkhunter: 2003’ten 2018’e kadar yazılmış 21K satırlık bir Bourne shell programı
  • Simplenetes: “Kubernetes in 17K lines of Shell” olarak tanıtılır
    • Dikkat çekici bir örnek olarak işaretlenmiş, ancak dormant durumda görünüyor
    • İlgili Hacker News Thread bağlantısı veriliyor
  • inxi 2.3.56: obsolete olarak işaretlenmiş 16K satırlık bir bash programı
    • 2008’de infobash’ten fork edildi
    • O sırada infobash 889 satırdı; infobash ise 2005’te başladı
    • v2.9’dan itibaren inxi, Perl uygulamasıyla değiştirildi
  • bashdb: Bir Bash hata ayıklayıcısıdır ve yaklaşık 14K satırlık bash ile yazılmıştır
  • romkatv/powerlevel10k: internal/ dizininde 12K satırlık zsh betikleri bulunur
    • Buna ek olarak config ve helper script’lerde 8K satır daha vardır
    • İlk commit 2014’tedir
  • dylanaraps/neofetch: Bash 3.2 ile yazılmış 10K satırlık bir programdır ve sistem bilgilerini gösterir
    • Görsellerle ilgili ilginç işlevler de yapabilir
    • İlk commit 2015’tedir
  • distrobox: Terminal içinde herhangi bir Linux dağıtımını kullanmayı sağlayan 7K satırdan uzun bir bash betiği
  • acme.sh: Sertifika çıkaran ve yenileyen 8K satırlık bir Shell betiği

Ölçeği küçük olsa da öne çıkan uygulamalar

  • bashforth: Yaklaşık 3.800 satır ile çok büyük değil, ama gerçek bir programlama dilini uygular
    • Çok sayıda boşluk ve yorum içerir
  • yoda: bashforth’un yaklaşık yarısı kadar boyutta, ama tüm yorumlayıcıyı ve derleyiciyi uygular
    • Aynı yazarın 20 yıl daha genç uygulaması olup daha fazla özellik içerir
    • Üzerinde “What learned you have, unlearn you must!” yorumu bulunur

Diğer önemli Shell programları

  • abcde / A Better CD Encoder: CD ripping için kullanılır ve yaklaşık 5.5K LoC’tir
  • thc-segfault: 3.3K LoC; büyük ölçüde Bash ile yapılmış bir pubnix sunucusu
  • ffmpeg/configure: FFmpeg’in elle yazılmış configure betiğidir ve 8.4K LoC’tir
  • ffhevc: FFmpeg ve libx265 ile HEVC video kodlayan, tamamen elle yazılmış bir Bash wrapper’ıdır ve 4K LoC’tir
  • ffx264: FFmpeg ve libx264 ile H.264/AVC video kodlayan, tamamen elle yazılmış bir Bash wrapper’ıdır ve 3.9K LoC’tir
  • h264enc: MEncoder ile H.264/AVC video kodlayan, tamamen elle yazılmış bir Bash wrapper’ıdır ve 9.2K LoC’tir
  • bashtop: 5.3K LoC’lik bir kaynak izleyici
  • halcyon: Haskell uygulamaları için bir kurulum sistemidir ve 6.6K LoC’tir
    • Bash semantiğine ve hata denetimine özen gösteren elle yazılmış koddur; fonksiyonel programlamadan ilham alan kendine özgü bir stile sahiptir
  • wordshell: Komut satırından birden fazla WordPress sitesini yöneten yaklaşık 7K satırlık kod
  • BaCon: Yaklaşık 10K satırdır ve BASIC ile yazılmış programları C’ye dönüştürür
    • Hem BASIC uygulaması hem de Shell betiği uygulaması vardır
  • FireHOL: Ana betik 9K satır, FireQOS aracı ise ek 3K satırdır
    • İnsan tarafından okunabilir yapılandırmadan secure, stateful firewall oluşturan hem bir dil hem de yürütülebilir programdır
  • gxadmin: 11K LoC; bilimsel iş akışı motoru Galaxy yönetimi için templated SQL query ve veri işleme yardımcı araçları koleksiyonudur
  • mulle-bashfunctions: bash/zsh için yaklaşık 6K satırlık bir fonksiyon kütüphanesi
    • mulle-sde içinde kullanılır ve mulle-sde de ayrıca 100K satırlık bir Shell betiğidir
  • x11docker: 11.6K satırdır ve docker veya podman container’larında GUI uygulamaları çalıştırır

Shell benzeri diller ve DSL’ler

  • modernish: Shell ile yazılmış, taşınabilir bir shell dialect’idir
  • bats: Test yazımı için bir DSL’dir ve bash kodu üretir
  • bashible: bash ile yazılmış, Ansible benzeri bir DSL’dir
    • İlgili comments bağlantısı verilir
  • clash: Tüm modern POSIX shell’lerle uyumlu nesne yönelimli bir framework’tür
  • bash Infinity: bash için standart kütüphane ve boilerplate framework’tür

Daha küçük programlar ve ilgili ekosistem

  • Alpine, Aboriginal ve Debian betikleri ayrı bir blog post bağlantısıyla verilir
  • completion betikleri büyüktür, ama çoğu zaman tekrarlıdır
    • _git Zsh completion’ı 8.3K satırlık koddur
    • git-completion.bash ve Docker completion da örnek olarak verilir
  • dyne/Tomb: Yaklaşık 3.500 satırlık bir zsh betiği
  • Basalt: Tam özellikli, saf Bash ile yazılmış bir package manager’dır
    • Birkaç bin satır ölçeğinde olsa da, 15’ten fazla uygulama ve kütüphane içeren zengin bir ekosisteme sahiptir
    • bash-core: trap ve shopt builtin’lerini genişleten, stacktrace ve temel kullanım kolaylıkları ekleyen bir kütüphane
    • bash-object: Saf Bash ile keyfî iç içe veri yapıları kuran bir kütüphane; yaklaşık 200 testi vardır
    • bash-json: Saf Bash ile JSON parse eden ve çıktı üreten bir kütüphane
  • tablespoon/fun/cli-clock: bash ile yazılmış çok satırlı karakter saat
  • json.bash / jb: JSON üreten bir komut satırı aracı ve bash kütüphanesi
    • Yaklaşık 1.700 satırdır ve testleri yaklaşık 3.000 satırdır

OSH testleri ve Shell kullanımında dikkat edilmesi gerekenler

  • OSH "Wild" Tests bir milyondan fazla satır Shell kodunu parse eder
    • Bunun büyük kısmı küçük programlar ve Alpine PKGBUILD, Gentoo ebuild gibi tekrarlı dağıtım paketi tanımlarıdır
  • Shell Programs That Run Under OSH, OSH altında çalışan Shell programlarının listesine bağlanır
  • shell script are dangerous, Shell’in sistemi etkileşimli konsol olarak ya da etkileşimsiz biçimde ele alan bir programlama ortamı olduğunu; çok işlevli, oldukça tehlikeli ve uygulama geliştirmek için tasarlanmış bir araç olmadığını hatırlatır

1 yorum

 
GN⁺ 2024-12-09
Hacker News yorumları
  • Yaklaşık 25 yıl önce Sony’de çalışırken, çok yavaş olan ve sık sık çöken bir sipariş yönetim sistemini düzeltme projesini üstlenmiştim.
    Kazdıkça OMS’nin, AIX sunucusunda çalışan devasa bir shell script yığınından oluştuğunu gördüm; 10 yılı aşkın süre evrilmiş, sonra da kendi haline bırakılmıştı. Kod 50 bin satırı aşıyordu; sipariş, ödeme ve diğer bilgiler FTP ile sunucular arasında taşındıktan sonra karmaşık sed/awk işlemleriyle parse ediliyor, stok da metin dosyalarında takip edilip FTP ile taşınıyordu.
    O dönemde Perl, bu keşmekeşi taşımak için en pratik seçenek gibi görünüyordu; en basit kısımlardan başlayıp küçük Perl modülleriyle değiştirerek, daha büyük bir Perl uygulaması içinde aşamalı olarak refactor ettik. 3 ay içinde tamamını yaklaşık 5 bin satır Perl’e indirdik; eski sistemdeki arızalar neredeyse tamamen kayboldu ve sistem 10 ila 100 kat hızlandı. Berbattı ama bugüne kadar yaptığım işler arasında en tatmin edici olanlardan biriydi.
    • Sadece 3 ay demek, her gün 800 satır silmek gibi bir şey.
      Eski kodun tamamını okuyup derinlemesine anlayarak davranışı birebir mi eşleştirdiniz, yoksa büyük parçaları atıp “bunun böyle çalışması gerekir” diye düşündüğünüz şekilde baştan mı yazdınız, merak ediyorum. Hızla değiştirilebilen çok fazla boilerplate olup olmadığını da merak ediyorum.
    • Böyle shell script canavarlarını hafifletmek için Perl hâlâ en pratik araç. Tcl de iyi bir seçenek.
  • Eskiden yazdığım şeyleri tekrar kurcalamam gerekecek.
    İlk yazdığım gerçekten büyük script, Enrust CA ve dizinleri için yaklaşık 7 bin satırlık bir kurulum programıydı; o dönemdeki neredeyse tüm Unix’lerde çalışması gerekiyordu. Baştan böyle değildi ama müşteri gereksinimleriyle büyüdü.
    Kurulumun kendisi çok karmaşık değildi ama yükseltme biraz karmaşıktı; o zamanlar her Unix’te tüm yardımcı programlar az çok farklıydı. Script’in önemli bir kısmı bu farkları tespit edip yönetmeye yönelik koddu; hata algılama, kurtarma, rollback, çok ilkel bir paket ve bağımlılık yönetimi de vardı.
    DEC’in Unix’i —Ultrix olmayanı— en anlaşılmaz olandı. Tüm komut satırı yardımcı programlarının çıktıları terminal sütun genişliğinde kırptığını fark etmem birkaç gün sürdü; aradan 30 yıl geçmesine rağmen hâlâ hatırlıyorum.
    HP-UX’te her sürümde kırıcı değişiklikler vardı ve yanlış hatırlamıyorsam 6.5’ten 11’e kadar destekliyorduk. Ultrix, Novell tarafı, NeXT ve Sequent’i pek hatırlamıyorum. AIX’in tuhaf olduğunu hatırlıyorum ama nedenini unuttum. Sun’ın üç/dört işletim sistemi arasında da farklar vardı; ama kılavuzları mükemmeldi, en iyisiydi.
    • Bu sütun genişliğinde kırpılan çıktı gerçekten tuhaf geliyor. Terminalde yatay kaydırma gibi bir özellik olmadığından emin miydiniz, merak ediyorum.
    • DEC’in Unix’i derken OSF/1, Digital Unix, Tru64 Unix’ten hangisini kastediyorsunuz?
    • Ben de binlerce satıra çıktım ama kabaca 2 bin satır civarındaydı. Yine de desteklemem gerekenlerin yalnızca güncel Red Hat ve Ubuntu olması şanstı.
    • Geçen yıl bir projenin ana ikili dosyası ve yardımcı kütüphaneleri üzerinde wc çalıştırdım; şu ana kadar 6.224 satır.
      Girdi protokol adaptörü, bir veya daha fazla filtre ve çıktı protokol adaptöründen oluşan konteyner kümeleriyle lineer garantili bir pipeline’ı yöneten bir script’ti. Amaç, konteyner ya da protokol uzmanı olmasalar bile dosyaların pipeline’dan geçerken nasıl filtrelenip dönüştürülmesini istediklerini bilen kişilerin kullanabilmesini sağlamaktı.
      En üst düzey ikili, git [ git options ] < git action> [action options] ya da systemctl gibi alt işlevler barındıran bir yapıda. Yeni alt komut ekleyen bir alt komut da var; gerekli kütüphaneleri oluşturuyor ve şablondan fonksiyon tanımlarını önceden dolduruyor. Şablonda kısa/uzun kullanım fonksiyonları var; böylece cbap -h ya da cbap pipeline -h faydalı yönlendirme veriyor.
      Temel imajları, bileşenleri ve pipeline’ları işleyen alt komutlar var. Kodun önemli bir kısmı, bileşen ve pipeline tanımlarının doğru yazıldığını doğrulamaya yönelik testler için. Pipeline neredeyse TOML’e yakın bir formatta olduğundan TOML parse etme ve bölümleri dizilere dönüştürme kodu var; bileşenler ise basit key=value dosyaları olduğu için sol/sağ tarafı çıkarma ve şema doğrulama kodu bulunuyor.
      Pipeline bileşenleri öznitelik paylaşabildiği için var ve etc dosyalarında ortak öznitelikleri bulmaya ve bileşen özniteliklerini belirtmeye yönelik kod da var. Güvenlik gereksinimlerine uygun kullanıcı, grup, dizin ve FIFO işleme fonksiyonları da çok. Bir pipeline yapılandırıldığında kullanıcı, grup, SELinux tipi ve MCS kategorileri oluşturulup uygulanıyor; ardından bunlar bileşeni başlatan servis dosyalarına eşlendiği için systemd işleme de çok fazla.
      En büyük çağrı kümesi muhtemelen bileşen özniteliklerini, aslında konteyner özniteliklerini alan ve ayarlayan fonksiyonlar. Veri odaklı konteyner tanımını olabildiğince esnek yapmak için her öznitelik için bir alma fonksiyonu, bir doğrulama fonksiyonu ve pipeline içi inline sürüm koyduk.
      Dosyalardan, ortam değişkenlerinden ve komut satırından değişken ayarlamak için Bash referanslarını yoğun kullanan kod da var; bu da hızlı test etmeyi mümkün kılıyor. Kullanıcı düzeyi olarak da kodun kendisiyle uğraşan bakımcı, bileşen tanımı geliştiren geliştirici, bileşenlerle pipeline oluşturan entegratör ve pipeline’ı kuran operatör olmak üzere dört seviyeyi destekliyor; her seviyedeki kullanıcıya dışa aktarmak için kendini kopyalayıp paketleyebiliyor.
      Hedef sistem herhangi bir Linux olabileceğinden makeself ile paketlenip çıkarılıyor. Örneğin entegratör bir pipeline tanımı oluşturduğunda bir makeself dosyası üretiliyor; hedef sistemde çalıştırıldığında tüm kullanıcıları, grupları, dizinleri ve FIFO’ları, yani bileşenler arası IPC’yi oluşturuyor; DAC/MAC uyguluyor, systemd dosyalarını oluşturuyor, imajları her kullanıcıya kopyalıyor ve pipeline’ı çalıştırıyor. Kaldırma seçeneğiyle bunların hepsini geri almak da mümkün.
      seccomp da kısmen var ama izin listesi ile engelleme listesi arasındaki dengeyi bulmak gerektiği için bir süreliğine durdu. ShellCheck’i gerçekten çok titiz kullanıyoruz.
  • Taşınabilirliği en üst düzeye çıkarmak için kendi script dilim Lil’in yorumlayıcısını Bash ile yazmayı bir ara düşündüm, ama kayan nokta aritmetiğinin aşırı acı verici olacağını çabucak fark ettim.
    Her ortamda bc/dc olduğunu varsayamazdım; elimdeki bazı makinelerde Bash sürümü eskiydi ve ilişkisel dizi desteği de çok sınırlıydı. Uzlaşma olarak AWK’yı hedef aldım; AWK, çoğu shell’den çok daha rahat bir genel amaçlı dil ve POSIX ortamı olan her yerde bulunuyor: https://beyondloom.com/blog/lila.html
    • Ben de bir dili shell’i hedef alacak şekilde yaparken bc/dcyi her ortamda varsayamayacağımı bizzat öğrendim.

WSL2’nin Ubuntu kurulumunda bc/dc olmadığını fark edince epey şaşırmıştım. Kayan nokta hesapları için AWK kullanıyorum ama sadece dış süreç olarak çağırma şeklinde.

  • Kariyerim boyunca birkaç kez büyük Perl programları yazıp bakımını yapmış biri olarak, insanların bunu yapmasının bir nedeni olduğunu düşünüyorum
    Java ya da Python gibi diller, arayüzler ve biçimler tanımlı olduğunda ve OS ile etkileşim neredeyse olmadığında iyi uyar. JSON/XML/YAML kullanmak ya da veritabanları ve başka programlarla HTTP(S) üzerinden konuşmak gibi durumlar, bu dillerin parladığı ideal koşulları yaratır
    Ama büyük miktarda metin ve OS etkileşimiyle uğraşınca Java ve Python ciddi bir eziyete dönüşür. Buna karşılık Shell/Perl’in bu işlerde çok daha rahat olduğunu hissedersiniz
    Neredeyse tüm otomasyon işleri, dağınık ve standartlaşmamış arayüzler, metin/günlük dosyaları, yapılandırılmamış ya da yeterince yapılandırılmamış veri biçimleri bu kapsama girer. Buna Perl’in geriye dönük uyumluluğu, geniş kurulu tabanı ve performansı da eklenince, bu işler için Perl dışında pratikte alternatif kalmaz
    Günümüzde büyük şirketlerin ufak tefek otomatikleştirilebilir işler için binlerce kişiyi işe aldığı yoğun manuel emeğin başlıca nedenlerinden birinin, uzun zamandır Perl kullanımının azalması olduğunu düşünüyorum. Python ya da Java ile büyük otomasyon işlerine kalkışınca, yazılması ve bakımı gereken kodun laf kalabalığına ve toplam büyüklüğüne bakıp kısa sürede vazgeçiliyor

    • “Bunun nedeni Perl’in ortadan kaybolması” görüşüne pek katılmıyorum. Bence karmaşıklık arttı; betikleri birbirine bağlayan Perl sorumlusunun yaptığı iş tam zamanlı bir işe dönüştü ve tek başına Perl’in de sınırları vardı
      Bu yüzden artık muhtemelen pahalı, tam zamanlı ek personele ihtiyaç duyuluyor. Son kullanıcı Windows kullanıyorsa masaüstünde zaten Perl’e benzer bir seçenek var: PowerShell; Perl’e benzer bir rol üstleniyor
    • Büyük otomasyon işini native kodla yaptım. Çünkü böyle durumlarda verimlilik önemli
      Bash+grep, metnin her satırı için yeni bir süreç çalıştırma eğilimine kolayca giriyor. Verimli yapmak için işi en aza indirmek gerekir; bunun için de toplu işleme ve tekilleştirme gerekir. Bu da tekilleştirme bağlamını izleyerek veriyi durumlu biçimde ele almak anlamına gelir ve düzgün bir programlama dilinde daha kolaydır
      Bash+grep durumsuz metin işleme için uygun olduğundan, iş tekrarının büyümesi kolaydır. İşi azaltmanın başka bir yolu da doğru filtrelemedir; bunu düzgün bir dilde imperatif biçimde temiz ifade etmek daha kolaydır. grep ve düzenli ifadeler bu amaç için hiç uygun değildir
      Satır tabanlı biçim kullanıldığında git, her şeyi kabul edebilmek için kaçış karakterleri ekliyor; destek tutarlı değil ve -z seçeneğiyle null sonlandırmalı dize biçimi istenerek bu devre dışı bırakılabiliyor. Bash’in bunu işlemenin bir yolu yok gibi; yeterince düşük seviyeli dillerde ise doğal biçimde ele alınabiliyor. Ayrıca her metin satırı için yeni bir süreç başlatmaya gerek bırakmayan kademeli streaming de mümkün
      Üstelik arada HTTP olsun ya da başka bir şey, tüm iş için tek bir kod tabanı kullanılabiliyor
    • Katılıyorum. En sevdiğim dil Python, ama bazı düşük seviyeli OS işleri için zahmetli ya da verimsiz olabiliyor. Bu yüzden https://www.oilshell.org ve bağlantılı wiki sayfasını oluşturdum
      Bağlam için birkaç bağlantı var. “Perl’i yeniden mi icat ediyorsunuz?”: https://www.oilshell.org/blog/2021/01/why-a-new-shell.html#a...
      “Unix shell, Perl 6/Raku gibi bir Big Bang değil; uyumlu yükseltme seçenekleri olan Perl 5 gibi evrilmeli”: https://www.oilshell.org/blog/2020/07/blog-roadmap.html#the-...
      YSH turu: https://www.oilshell.org/release/latest/doc/ysh-tour.html
    • Perl’in birçok Linux ve BSD sisteminde varsayılan olarak kurulu olduğunu fark ettiğimden beri Perl 5’i ciddi ciddi öğrenmeyi düşünüyorum. Bildiğim kadarıyla OpenBSD de Perl kurulu geliyor
      İnternetten bir şey kuramayacağınız ya da hiç internete erişemeyen bir ortamda çalışana kadar bu büyük bir avantaj gibi görünmeyebilir
  • Büyük programları Bash betiği olarak yazmanın temel sorunu, shell betik dilinin en başta karmaşıklık için tasarlanmamış olması
    Küçük komutları koordine etmekte ve mevcut araçları hızlı, keşifsel biçimde birbirine bağlamakta harika; ama Bash birkaç yüz satırı aşmaya başladığında, uzun vadeli bakım ve ölçeklenebilirliği baş ağrısına çeviren sınırlamalar peş peşe ortaya çıkıyor
    Öncelikle okunabilirlik sorun. Bash söz dizimi büyüdükçe gerçekten anlaşılması zorlaşabiliyor. Değişken kapsamı kuralları incelikli, hata yönetimi ilkel ve dize işleme kısa sürede dağınık hale geliyor. Sonunda bakım yapan kişi ne olduğunu çözmeye zaman harcıyor ve güvenle değişiklik yapmak da zorlaşıyor
    Sırada sağlam araç eksikliği var. Daha olgun dillerde yaygın hataları erken yakalayan statik analiz araçları, linter’lar ve debugger’lar var. Bash’te bunlar ya yok ya da çok sınırlı. Bu güvenlik ağları olmayınca büyük Bash programları sessiz hatalara, regresyonlara ve sinsi bug’lara daha açık hale geliyor
    Test de sorun. Bash betikleri test edilebilir, ama süreç genellikle daha zahmetlidir; karmaşık mantık ya da veri yapıları olduğunda daha da zorlaşır. Dosya adlarındaki boşluklar veya beklenmedik ortam koşulları gibi sınır durumlarıyla uğraşırken, doğrulaması acı verici bir sürü savunmacı kod ortaya çıkar
    Son olarak ekosistemin kendisi büyük ölçekli Bash geliştirme için kurulmuş değil. Modülerlik, paket yönetimi, standartlaştırılmış bağımlılık yönetimi ve Python ya da Go’nun sunduğu modern geliştirme kalıplarını kaybedersiniz. Zamanla bu eksikler birikerek sizi yavaşlatır
    Tek seferlik işler ya da basit otomasyon için Bash kullanmak gayet iyi. Bash’in iyi yaptığı şey bu. Ama büyük bir şey inşa etmeyi düşünüyorsanız, genelde karmaşık uygulamalar oluşturup bakımını yapmak için tasarlanmış bir dil kullanmak daha iyidir; başlangıçtaki öğrenme eğrisi ya da kurulum biraz daha yüksek olsa bile uzun vadede zaman kazandırır

  • ShellCheck’i linter olarak kullanırsanız yaygın tuzakların çoğunu yakalayabilirsiniz. Bash/shell’de gerçekten çok sayıda tuzak ve beklenmedik davranış var; deneyimli Bash yazarları bile bunlara takılabiliyor
    Yine de Bash/shell, dil hiyerarşisinde kendine özgü bir konumda. Neredeyse her yerde var ve 30 yıl sonra da var olma olasılığı yüksek. Neredeyse her yerde çalışacak ve 30 yıl sonra da çalışmasını istediğiniz bir program istiyorsanız shell/Bash iyi bir seçimdir

    • Şu an iş yerinde tam da bunu yaşıyorum. Binlerce satırlık Bash kodunu kurcalıyorum
      Çok eski yazılmış bir script de değil; neden Bash’i seçtiklerini bilmiyorum. Script çalışıyor ama koda yanlış açıdan baksam bir şeyler kırılacakmış gibi geliyor
    • Bash/ksh’de hata ayıklama ve izleme argümanı olarak -x var
  • Eskiden düzenli kullandığım en büyük elle yazılmış shell programı muhtemelen abcde (A Better CD Encoder) idi; yaklaşık 5.500 satırdı
    https://abcde.einval.com
    https://git.einval.com/cgi-bin/gitweb.cgi?p=abcde.git;a=blob...

    • İyi bildiğimi söyleyemem ama eskiden What.CD’de önerilen araçlardan biriydi. Arkadaşlarım Max’in de birlikte önerildiğini söylemişti: https://github.com/sbooth/Max
    • Kullanmıştım; gerçekten iyi çalışıyordu ve kullanımı da oldukça kolaydı. Tamamının dev bir shell script’i olduğunu hiç bilmiyordum
  • Bu programların epey bir kısmı gerçek birer mücevher. Örneğin rkhunter script’inin kodu fena değil, geliştirmeye de açık ve aynı zamanda bir bilgi hazinesi
    Bu tür script’lerde kod boyutunun büyük bir bölümü, çeşitli platformlarda gerekli yardımcı araçların mevcut olduğunu ve farklı komut satırı seçenekleriyle beklendiği gibi davrandığını garanti etmeye harcanıyor. Ciddi shell script yazarları için en acı veren nokta bu; sinyallerden ve alt süreçlerden bile daha zor
    rkhunter “düzgün” bir programlama diliyle yazılmış olsaydı bu bilgilerin daha az şeffaf olacağını düşünüyorum. Veriler, bir veri yapısının içindeki kayıtlara itilip sorgulanabilir ya da iç içe veri yapıları üzerinde birden çok fonksiyonla, hatta daha kötüsü metot ve sınıf kombinasyonlarıyla çalıştırılabilirdi. Loglar da JSON’a parçalanıp veritabanına sıkıştırılır ve başka metotlarla erişilmesi gerekebilirdi
    Shell script’leri böyle karmaşık araçlara sahip olmadığı için, olan biteni olduğu gibi ortaya serme eğiliminde. Bu yüzden rkhunter, çeşitli exploit’ler ve rootkit’ler için de fena olmayan bir dokümantasyon işlevi görüyor; dosyadan dosyaya, yapıdan yapıya, veritabanından veritabanına kazı yapma ihtiyacı daha az

  • FreeBSD Update istemcisi yaklaşık 3.600 satır sh kodundan oluşuyor
    Burada anılan diğer programlarla karşılaştırıldığında büyük değil ama “tüm işletim sistemini güncelleyen araç” işlevi açısından epey ağır bir iş yaptığını düşünüyorum. Güncellemeleri oluşturan kod birden çok dosyaya dağılmış durumda; toplarsanız daha fazla olacaktır

  • “Sadece” 7,1 bin satır olsa da benim sevdiğim, Let’s Encrypt’ten sertifika almak ve yenilemek için kullanılan acme.sh script’i
    https://github.com/acmesh-official/acme.sh/blob/master/acme....

  • Bazen kullanılabilir olduğunu garanti edebileceğiniz tek şey shell olabilir ve taşınabilirlik gerçekten gerekli olabilir
    Ama genel olarak elinizde devasa bir shell uygulaması varsa hayatınızdaki seçimleri yeniden düşünmeniz gerekebilir

    • Sorun “hangi shell?” meselesi. Bash evrensel olmaktan çok uzak
      Üstelik genelde yalnızca shell ile yapabileceğiniz şeyler sınırlı; find, grep, sed, cat, head, tail, cut gibi komutlara ihtiyaç duyarsınız. Bu komutların da kendi taşınabilirlik sorunları var
      BusyBox’ı hedeflemek en iyi seçenek olabilir ama tipik bir Linux sisteminin dışına çıktığınız anda taşınabilir Bourne shell script’i yazmak zorlaşıyor, hatta neredeyse imkânsız hale geliyor
    • Bu tür şeyleri epey sık duyuyorum; shell’in olup C derleyicisinin olmadığı ya da shell üzerinden C derleyicisi kurmanın mümkün olmadığı durumların gerçekte ne kadar yaygın olduğunu gerçekten merak ediyorum
      Bir C derleyiciniz varsa shell’den çıkıp C programları yazarak bunları shell script’ine birleştirtmek ya da Lua gibi daha iyi bir script dili kurmak mümkün. Günümüzde mutlaka yalnızca shell kullanmanız gereken durumlar bana oldukça niş geliyor