1 puan yazan GN⁺ 2 시간 전 | 1 yorum | WhatsApp'ta paylaş
  • Shell'deki : hiçbir işlem yapmadan sadece argümanları değerlendiren bir null command'dır; parametre genişletmeyle birleştirildiğinde zorunlu argüman kontrolü ve varsayılan değer atamayı kısa biçimde yapabilir
  • : "${1:?missing argument, aborting!}" ifadesi, $1 yoksa veya boşsa tanı mesajını stderr'e yazar ve sıfır olmayan bir durum koduyla çıkar
  • ${VAR:=default} ifadesi : komutunun argümanı olarak verilirse genişletme çalışır ama ortaya çıkan string atılır; böylece genişletme sonucunu komut olarak çalıştırmadan yalnızca varsayılan değer atanabilir
  • Dosya boşaltma ve erişilebilirlik kontrolü için yönlendirme ile birlikte, trap içindeki boş komut, set -u ortamındaki değişken kontrolleri ve boş koşul dallarında da : kullanılabilir
  • : "${VAR:=default}" değişken adını yalnızca bir kez yazarak yazım hatası olasılığını azaltır ve while: içinde her zaman başarılı olan bir koşul olarak sonsuz döngüyü ifade eder

Null command ve parametre genişletme

  • :, argümanları değerlendirdikten sonra sonucu atan bir null command yerleşik komutudur
    • Kökeni 1971'deki Thompson shell'e kadar gider; o dönemde label ve Unix'in ilk yorum işareti olarak da kullanılmıştır
  • Dört satırlık bir koşul bloğu yerine şu tek satırla zorunlu argüman kontrolü yapılabilir
: "${1:?missing argument, aborting!}"
echo "Hello $1!"
  • Parametre genişletme söz dizimi ${name:?diagnostic}, $name değişkeninin tanımlı olup olmadığını ya da boş olup olmadığını kontrol eder
    • Değer yoksa diagnostic mesajını stderr'e yazar ve shell'i sıfır olmayan bir durum koduyla sonlandırır
    • Değer varsa $name ile aynı sonucu üretir
  • Null command olmadan yalnızca ${HELLO:=123} çalıştırılırsa, genişletme sonucu olan 123 bir komut gibi ele alınır ve command not found hatası oluşur
    • : ${HELLO:=123} ifadesi genişletmeyi değerlendirip HELLO=123 atamasını yapar, ama sonucu atar
  • : "${DATA_DIR:=/var/data}", DATA_DIR="${DATA_DIR:-/var/data}" ifadesinden farklı olarak değişken adını yalnızca bir kez yazar; böylece DATA_DRI gibi yazım hatası olasılığını azaltır

: kullanma yolları

  • Varsayılan değer atama

    • Genişletme sonucunu çalıştırmadan atarken değişkenin varsayılan değerini belirler
: "${DATA_DIR:=/var/data}"
: "${RETRIES:=3}"
  • Dosya boşaltma ve erişim kontrolü

    • Yönlendirme ile birleştirildiğinde bir veya daha fazla dosyayı boşaltabilir
: > error.log
: > error.log > access.log
  • Alt kabuk ve yönlendirme kullanılarak dosyanın okunabilir ya da yazılabilir olup olmadığı da kontrol edilebilir
( : < dataset.json ) && echo YES
( : >> result.json ) && echo YES
  • Boş komut gereken yerler

    • trap gibi söz dizimi gereği bir komutun gerektiği ama gerçekte hiçbir iş yapılmaması gereken durumlarda kullanılabilir
trap : INT
sleep 60
  • Koşul ifadelerinde boş bırakılacak dallara da yerleştirilebilir
if some-command; then
    :
else
    echo "command failed"
fi
  • Birden çok değişkeni kontrol etme

    • set -u etkin durumdayken birden çok değişkenin tanımlı olup olmadığını tek seferde kontrol eder
set -u
: "$DEPLOY_ENV" "$HOST"
  • Sonsuz döngü

    • : her zaman başarılı olan bir koşul olduğu için sonsuz döngü kısa ve net biçimde yazılabilir
while :; do
  echo "I love colons"
  sleep 1
done

1 yorum

 
GN⁺ 2 시간 전
Lobste.rs yorumları
  • Promptu aşağıdaki gibi yapılandırırsanız satırın tamamını kopyalayıp yapıştırsanız bile prompt kısmı yok sayılır, yalnızca komut çalıştırılır
    : hayalci@tassadar ~/src/dool ; jj rebase -s dxw -d mrn
    • Plan 9’dan esinlenerek shell’in autocd seçeneğini ve şu biçimi de kullanıyorlar
      ~/directoryname; <command>
      Shell’in komut satırını her kopyaladığınızda, komutun ilk çalıştırıldığı dizine tekrar tekrar cd edilmiş olur
    • zsh’de görünmeyen, satır sonu olmayan boşluk yapıştırıldığında soldaki içeriği silecek şekilde ayarlıyorlar
      nbsp=$'\u00A0'  
      PS1="...$nbsp"  
      bindkey -s $nbsp '^u'  
      
  • Makefile’da çıktıyı daha okunur göstermek için iki nokta üst üste sıkça kullanılıyor
    out/%.o: src/%.c  
        @echo CC $@  
        @$(CC) -c -o $@ $<  
    
    Bu yöntemde make, birden fazla echo sürecini aynı anda çalıştırıp aynı stream’e çıktı verdirdiği için çıktılar birbirine karışabilir. Aşağıdaki gibi değiştirildiğinde çıktı, alt süreçten değil make sürecinin kendisinden gelir
    out/%.o: src/%.c  
        : CC $@  
        @$(CC) -c -o $@ $<  
    
  • Shell betiklerinde bu tekniği görmüştüm ama man : veya whatis : ile işe yarar bir belge bulmak zordu
    true komutuna benzer, ancak --help, --version gibi seçeneklere özel tepki vermez ve daha az karakterlidir
    • Bash yerleşik komutları man yerine help ile aranmalı
      $ help :  
      :: :  
          Null command.
      
          No effect; the command does nothing.
      
          Exit Status:  
          Always succeeds.  
      
    • Fish’te : kelimenin tam anlamıyla true için bir alias’tır
  • İki nokta üst üste olmadan da parametre genişletmesi gerçekleşiyor; bu yüzden özellikle null komuta neden ihtiyaç olduğu merak ediliyor
    • Parametre genişletmesi yine gerçekleşir, ancak null komutta olduğu gibi sonucu tüketecek bir söz dizimi yoksa shell genişletilmiş string’i çalıştırılacak komut olarak ele alır. Bu bilgi SSS’ye de eklendi
      % ${HELLO:=123}  
      zsh: command not found: 123  
      
      % : ${HELLO:=123}  
      % echo $HELLO  
      123  
      
    • İnterpole edilen string’in sonucu, çalıştırılacak komut olarak yorumlanır
      #!/bin/sh  
      "${1:?missing argument, aborting!}"  
      
      $ sh foo.sh sh  
      sh-5.3$  
      
  • Bir komutu yazarken daha sonra yeniden çalıştırmak istediğimde satırın en başına iki nokta üst üste koyup geçmişe kaydediyorum. Sonra geçmişte o satırı bulup yalnızca ilk karakteri silerek gerçekten çalıştırabiliyorum
    Ancak argümanları değerlendirirken oluşan yan etkiler için kullanmayı düşünmemiştim
    • : yerine # koyup yorum olarak kaydetmek de mümkün. Daha sonra çalıştırılacak bir şeyse, içindeki ifadelerin önceden değerlendirilmemesi avantajı var
    • zsh’de Meta-q veya Alt-q ile mevcut satırı geçici olarak kenara alıp başka bir komut çalıştırabilir, bitince asıl satırı komut satırı arabelleğine geri getirebilirsiniz
      https://nathangrigg.com/2014/04/zsh-push-line-or-edit/
  • macOS’ta hâlâ Bash 3 kullanılıyor ve şu hata oluşuyor
    -bash: !}": event not found
    • "!" kullanımını kaldırınca çalışıp çalışmadığı merak ediliyor
  • Con-colon-sion bölümündeki şu kodun insanları while true; do...’dan daha çok şaşırtma olasılığı yüksek
    while : colons are more than punctuation; do  
      echo "I love colons"  
      sleep 1  
    done  
    
    while true; do, while :; do’dan yalnızca üç karakter daha uzun, yani yeterince kısa; bu kod da yazarın anlatmak istediği noktaya uygun bir örnek gibi görünmüyor
    • Harfi harfine uygulanacak bir örnek değil, kelime oyunu olarak eklenmiş bir kod. Bu kodu anlayabiliyorsanız null komutu biliyorsunuz demektir; iki nokta üst üste gerçekten noktalama işaretinden fazlasını ifade eder
    • Aslında gösterilmek istenen şey muhtemelen aşağıdaki gibi bir sonsuz döngüydü, ama havalı ifade etmeye çalışırken asıl nokta kaçmış gibi
      while :; do  
          something  
      done