Komut Satırı Arayüzü Rehberi (2021)
(clig.dev)- Geleneksel UNIX felsefesini modern bir yaklaşımla yeniden yorumlayan, CLI programları için tasarım ilkelerini ve somut yönergeleri açık kaynaklı bir belge olarak derleyen bir referans; temel hedef kitlesi komut satırı araçları geliştiren yazılımcılar
- CLI, basit bir betikleme platformu olmaktan çıkıp insan merkezli bir metin tabanlı UI olarak evrildi; bu değişime uygun olarak tasarım ilkelerinin de güncellenmesi gerekiyor
- Birleştirilebilirlik (composability) ve insan dostuluğu birbiriyle çelişmez; standart giriş/çıkış, pipe ve çıkış kodu gibi UNIX geleneklerine uyularak ikisi aynı anda sağlanabilir
- Yardım metinleri, hata mesajları, çıktı biçimi, etkileşimlilik, yapılandırma sistemi gibi pratikte sık gözden kaçan ayrıntılar için de somut öneriler sunuyor
- CLI araçlarının geleceğe uyumluluğu ve kullanıcı güveni, arayüz istikrarı ve analiz verisi şeffaflığıyla belirlenir; bu rehber de bunun için bir temel çizgi sunuyor
Felsefe (Philosophy)
İnsan merkezli tasarım
- Geleneksel UNIX komutları çoğunlukla diğer programlar tarafından kullanılacak şekilde tasarlanmıştı; ancak bugün CLI çoğunlukla insanlar tarafından doğrudan kullanıldığı için insan öncelikli tasarım gerekiyor
- Geçmişte CLI "machine-first" idi, bugün ise "human-first" metin tabanlı bir UI'ye dönüştü
Birleştirilebilir küçük parçalar
- UNIX felsefesinin özü, küçük ve basit programları birleştirerek daha büyük sistemler kurmaktır ve bu anlayış bugün de geçerlidir
- Standart
stdin/stdout/stderr, sinyaller ve çıkış kodları programlar arası bağlantıyı garanti eder; JSON ise daha yapılandırılmış veri alışverişini destekler - Yazılım mutlaka daha büyük bir sistemin parçası olur; iyi çalışan bir parça olup olmayacağı tasarım aşamasında belirlenir
Tutarlılık
- Terminal kullanıcıları mevcut konvansiyonlara alışkındır; bu nedenle CLI'nin mevcut kalıpları izlemesi önerilir
- Ancak tutarlılık kullanılabilirliğe zarar veriyorsa, gelenek dikkatle bozulabilir
Uygun bilgi miktarı
- Bir komut birkaç dakika boyunca hiçbir çıktı vermeden bekliyorsa "çok az", büyük miktarda debug log döküyorsa "çok fazla" bilgi veriyordur
- Bilgi miktarındaki denge, yazılımın kullanıcıyı desteklemesi açısından kritik öneme sahiptir
Keşfedilebilirlik (Ease of Discovery)
- GUI tüm işlevleri ekranda açıkça gösterirken, CLI'nin hafızaya dayalı olduğu yönünde yanlış bir algı vardır
- Kapsamlı yardım metinleri, zengin örnekler ve sonraki komut önerileri gibi GUI tekniklerinden yararlanılarak CLI de öğrenmesi kolay hale getirilebilir
Bir diyalog olarak CLI
- CLI kullanımı, tekrar eden deneme-yanılma üzerinden ilerleyen bir diyalog yapısına sahiptir; hata düzeltme önerileri, ara durum gösterimi ve riskli işlemler öncesi onay bu özelliği kullanan tasarım teknikleridir
- En kötü etkileşim, kullanıcıyı çaresiz hissettiren düşmanca bir diyalogdur; en iyisi ise başarı hissi veren keyifli bir alışveriştir
Sağlamlık (Robustness)
- Yazılım hem gerçekte hem de hissettirdiği şekilde sağlam olmalıdır
- Beklenmeyen girdilerin zarif biçimde ele alınması, idempotence'ın korunması, ilerleme durumunun bildirilmesi ve stack trace'in gereksiz yere gösterilmemesi temel unsurlardır
- Karmaşık özel durumlar azaltılıp tasarım sade tutulursa sağlamlık artar
Empati
- CLI araçları, geliştiricinin yaratıcı araçlarıdır; bu yüzden kullanımı keyifli olmalıdır
- Kullanıcının aracın kendi tarafında olduğunu hissetmesini sağlayacak şekilde sorunlar yeterince düşünülerek tasarlanmalıdır
Kaos
- Terminal dünyası tutarsızlıklarla doludur; ancak bu kaos aynı zamanda özgür yaratıcılığın da kaynağıdır
- "Bir standart üretkenliğe ya da kullanıcı memnuniyetine açıkça zarar veriyorsa, o standardı terk edin." — Jef Raskin
Yönergeler — Temeller (The Basics)
- Argüman ayrıştırma kütüphanesi kullanın: dil bazında önerilen kütüphaneler arasında Go(Cobra, cli), Python(Click, Typer, Argparse), Rust(clap), Node(oclif) ve daha fazlası bulunur
- Başarı durumunda çıkış kodu 0, hata durumunda ise 0 dışı bir kod döndürün — betikler başarıyı ve hatayı buna göre ayırt eder
- Varsayılan çıktı
stdout'a, log ve hata gibi mesajlar isestderr'a gönderilmelidir
Yönergeler — Yardım (Help)
-hveya--helpbayrağıyla ayrıntılı yardım metni gösterin; aynı ilkeyi alt komutlarda da uygulayın- Argümansız çalıştırıldığında kısa yardım gösterin (açıklama, 1-2 örnek, bayrak açıklamaları ve
--helpyönlendirmesi dahil)jq, bunun iyi uygulanmış bir örneği olarak anılıyor
--help/-h/help subcommandgibi farklı yardım isteme biçimlerinin tümünü destekleyin- Yardım metninin üst kısmında web dokümantasyonu bağlantısı ve geri bildirim kanalı sağlayın
- Örnekleri önce gösterin — karmaşık kullanım senaryolarına kademeli biçimde ilerleyen bir anlatı önerilir
- Sık kullanılan bayrakları ve komutları yardım metninin üst kısmına yerleştirin (
gitin yapısı örnek alınabilir) - Kalın başlıklar gibi biçimlendirmeleri taramayı kolaylaştıracak şekilde kullanın; ancak terminalden bağımsız yöntemler tercih edin
- Kullanıcı yanlış giriş yaptığında niyetini tahmin edip düzeltme önerebilirsiniz — ancak otomatik çalıştırma kararı dikkatle verilmelidir
- Yanlış giriş basit bir yazım hatası değil, mantıksal bir hata olabilir; ayrıca otomatik düzeltme yapılırsa o sözdizimini kalıcı olarak destekleme yükü doğar
Yönergeler — Dokümantasyon (Documentation)
- Web tabanlı dokümantasyon sağlayın — aranabilirlik ve bağlantı paylaşımı için gereklidir
- Terminal tabanlı dokümantasyon sağlayın — kurulu sürümle senkron kalır ve çevrimdışı erişilebilir
- man sayfası sunmayı değerlendirin —
ronngibi araçlarla üretilebilir;npm help lsgibi alt komut üzerinden erişim önerilir
Yönergeler — Çıktı (Output)
- İnsan tarafından okunabilirlik önceliklidir — çıktının insan için mi olduğunu TTY olup olmamasına göre belirleyin
- Metin akışları UNIX'in evrensel arayüzüdür; bu nedenle makine tarafından okunabilir çıktı da desteklenmelidir
- İnsan dostu çıktı pipe uyumluluğunu bozuyorsa,
--plainbayrağıyla düz metin çıktı sunun --jsonbayrağı verildiğinde JSON biçiminde çıktı destekleyin- Başarı durumunda çıktı kısa olsun; gerekmiyorsa hiç çıktı üretmeyin — betik kullanımı için
-qseçeneğiyle çıktıyı bastırmayı destekleyin - Durum değiştiğinde kullanıcıyı bilgilendirin —
git pushun uzak branch durumunu göstermesi iyi bir örnektir git statusgibi, mevcut sistem durumunu kolayca görmeyi ve sonraki adımı anlamayı sağlayan çıktılar tasarlayın- Renkleri bilinçli kullanın; pipe durumu,
NO_COLOR,TERM=dumb,--no-colorgibi koşullarda renkleri devre dışı bırakmak zorunludur - TTY olmayan ortamlarda animasyon veya spinner göstermeyin (CI loglarının kirlenmesini önlemek için)
- Emoji ve sembolleri yalnızca açıklığı artırdıklarında kullanın (
yubikey-agentörnek olarak veriliyor) - Yalnızca geliştiricinin anlayacağı bilgiler varsayılan çıktıdan çıkarılmalı, sadece verbose modunda gösterilmelidir
stderr'ı log dosyası gibi kullanmayın — varsayılan olarakERR,WARNgibi log seviyesi etiketlerini göstermeyin- Büyük hacimli çıktılarda
lessgibi bir pager kullanmayı değerlendirin — yalnızca TTY ortamında etkinleştirin veless -FIRXseçeneğini önerin
Yönergeler — Hatalar (Errors)
- Öngörülebilir hataları insanın anlayabileceği mesajlarla yeniden yazın (ör. "
chmod +w file.txtçalıştırmanız gerekiyor") - Sinyal/gürültü oranını koruyun — aynı türden hataları tek bir başlık altında gruplayarak gösterin
- Önemli bilgileri çıktının son kısmına yerleştirin — kırmızı metni bilinçli ve nadiren kullanın
- Beklenmeyen bir hata oluştuğunda debug bilgisi ve bug raporu gönderme yöntemi de ekleyin
- Bug raporu URL'sine bilgileri otomatik doldurarak gönderimi kolaylaştırın
Yönergeler — Argümanlar ve Bayraklar (Arguments and Flags)
- Argümanlar (
args) konuma dayalıdır, bayraklar (flags) ise isme dayalıdır — argümanlara kıyasla bayrakları tercih edin - Tüm bayraklar için uzun ad sürümü sağlayın (ör.
-hile birlikte--help) - Tek karakterli bayrakları yalnızca sık kullanılanlar için ayırın
- Bir standart varsa standart bayrak adlarını kullanın (
-f/--force,-q/--quiet,-v,--jsonvb.) - Varsayılan değerleri çoğu kullanıcıya uygun olacak şekilde belirleyin
- Argüman veya bayrak verilmediğinde prompt ile giriş isteyin, ancak etkileşimsiz ortamlarda prompt'u zorlamayın
- Riskli işlemlerden önce onay isteyin — risk düzeyine göre
y/nonayı, dry-run ya da doğrudan metin yazdırma gereksinimi kullanın- Risk düzeyi mild (dosya silme), moderate (dizin silme, uzak kaynağı değiştirme), severe (tüm sunucuyu silme) olarak ayrılır
- Dosya girdi/çıktısında
-ilestdin/stdoutüzerinden okuma ve yazmayı destekleyin (ör.curl ... | tar xvf -) - Bayraklar üzerinden gizli bilgi doğrudan almayın —
--password-filebayrağı veyastdinkullanımı önerilir (psçıktısı ve shell geçmişine sızma riski)
Yönergeler — Etkileşimlilik (Interactivity)
- Prompt ve etkileşimli öğeleri yalnızca
stdinbir TTY ise gösterin --no-inputverildiğinde tüm prompt'ları devre dışı bırakın- Parola girişinde echo'yu kapatın (girilen içerik ekranda görünmemeli)
- Kullanıcının her zaman kaçış yolu olduğunu açıkça gösterin — Ctrl-C her zaman çalışır durumda kalmalıdır
Yönergeler — Alt Komutlar (Subcommands)
- Alt komutlar arasında bayrak adları ve çıktı biçimi tutarlılığını koruyun
- Karmaşık araçlarda
noun verbveyaverb nounbiçiminde iki seviyeli alt komut yapısı kullanın (ör.docker container create) - Belirsiz ya da birbirine benzeyen adlı alt komutlardan kaçının (ör.
updateileupgradeı birlikte kullanmamak)
Yönergeler — Sağlamlık (Robustness Guidelines)
- Girdi doğrulamasını erken aşamada yapın; hatalı verilerde anlaşılır bir hata verip erkenden çıkın
- Tepkisellik hızdan daha önemlidir — 100 ms içinde bir şeyler gösterin
- Uzun süren işlerde ilerleme çubuğu (progress bar) sağlayın — Python(
tqdm), Go(schollz/progressbar), Node(node-progress) kütüphaneleri kullanılabilir - Paralel işlem sırasında çıktının birbirine karışmamasına dikkat edin
- Ağ zaman aşımı ayarlayın — varsayılan değerlerle birlikte, sonsuza kadar beklemeyi önleyin
- Geçici bir hatadan sonra yeniden denendiğinde önceki durumdan devam edebilecek şekilde tasarlayın
- Crash-only tasarım benimseyin — temizleme işlemine gerek kalmadan hemen sonlanabilen yapılarla idempotence sağlayın
Yönergeler — Geleceğe Uyumluluk (Future-proofing)
- Değişiklikleri geriye dönük uyumlu, eklemeli (additive) biçimde tutun
- Uyumluluğu bozacak bir değişiklikten önce program içinde önceden uyarı gösterin
- İnsanlara yönelik çıktının değişmesi genelde kabul edilebilir — betikler için
--plainve--jsonkullanımını teşvik edin - Catch-all alt komutları yasaklayın — ileride aynı adda alt komut eklenememesi sorununa yol açar
- Alt komut kısaltmalarını otomatik kabul etmeyin — yalnızca açıkça tanımlanmış alias'lara izin verin ve bunları kararlı biçimde koruyun
- "Time bomb" tasarımlardan kaçının — 20 yıl sonra da çalışabilecek şekilde dış bağımlılıkları en aza indirin
Yönergeler — Sinyaller ve Kontrol Karakterleri (Signals)
- Ctrl-C (
INTsinyali) alındığında hemen çıkın; temizleme işlemleri için zaman aşımı belirleyin - Temizleme sırasında Ctrl-C tekrar girilirse zorla çıkılabileceğini belirtin (Docker Compose örneğine bakılabilir)
- Programı, temizleme işlemleri tamamlanmamış bir durumda başlatılabileceği varsayımıyla tasarlayın
Yönergeler — Yapılandırma (Configuration)
Yapılandırma uygulama önceliği (yüksek → düşük):
- Bayraklar → mevcut shell ortam değişkenleri → proje düzeyi yapılandırma (
.env) → kullanıcı düzeyi yapılandırma → sistem geneli yapılandırma
Yapılandırma türüne göre öneriler:
-
Her çağrıda değişen ayarlar (debug seviyesi, dry-run): bayrak kullanın
-
Proje ya da makineye göre değişen ayarlar (yollar, renk, HTTP proxy): bayrak + ortam değişkeni kombinasyonu
-
Proje genelinde paylaşılan ayarlar (Makefile,
package.jsontürü): sürüm kontrolündeki dosyaları kullanın -
XDG Base Directory spec'e uyun —
~/.configtabanlı yapılandırma yolları önerilir (yarn,fish,neovim,tmuxgibi araçlar destekler) -
Başka programların yapılandırma dosyalarını otomatik değiştirirken mutlaka kullanıcı onayı alın
Yönergeler — Ortam Değişkenleri (Environment Variables)
- Ortam değişkenleri, çalışma bağlamına göre değişen davranışlar için uygundur
- Adlarda yalnızca büyük harf, rakam ve alt çizgi kullanın; rakamla başlamayın
- Tek satırlık değerler önerilir — çok satırlı değerler
envkomutuyla uyumluluk sorunlarına yol açabilir NO_COLOR,DEBUG,EDITOR,HTTP_PROXY,SHELL,TMPDIR,HOME,PAGERgibi genel amaçlı ortam değişkenlerini önce kontrol edin- Proje bazlı
.envdosyası okuma desteği önerilir — ancak.env, resmî yapılandırma dosyasının yerini tutmaz.envsınırlamaları: sürüm kontrolüne girmez, geçmiş tutmaz, yalnızca string tipine sahiptir, kodlama sorunlarına açıktır
- Gizli bilgileri ortam değişkenlerinden okumayın — tüm süreçlere yayılır, loglara sızabilir,
Docker inspectveyasystemctl showile ortaya çıkabilir- Gizli bilgiler yalnızca kimlik bilgisi dosyaları, pipe,
AF_UNIXsocket'leri veya secret management servisleri üzerinden alınmalıdır
- Gizli bilgiler yalnızca kimlik bilgisi dosyaları, pipe,
Yönergeler — Adlandırma (Naming)
- Basit ve akılda kalıcı sözcükler kullanın — aşırı genel adlar başka komutlarla çakışabilir
- Yalnızca küçük harf ve gerekirse tire kullanın (
curliyi bir örnek,DownloadURLkötü bir örnek) - Kısa tutun; ancak
cd,ls,psgibi aşırı kısa adlar genel amaçlı yardımcı programlar için ayrılmıştır - Docker Compose'un önceki adları olan
plum→fig→docker compose, yazma kolaylığının adlandırmada ne kadar önemli olduğunu gösteren gerçek bir örnektir
Yönergeler — Dağıtım (Distribution)
- Mümkünse tek bir binary olarak dağıtın —
PyInstallergibi araçlar kullanılabilir - Tek binary mümkün değilse platforma özgü yerel paket kurucularını kullanın
- Kaldırma yöntemini kurulum talimatlarının altında açıkça belirtin
Yönergeler — Analiz Verileri (Analytics)
- Kullanıcı onayı olmadan kullanım verisi veya crash verisi göndermeyin
- Veri toplanıyorsa nelerin toplandığını, neden toplandığını, nasıl anonimleştirildiğini ve ne kadar süre saklandığını açıkça paylaşın
- Varsayılan olarak opt-in önerilir — opt-out kullanılacaksa ilk çalıştırmada ya da web sitesinde açıkça bildirin
- Angular.js (açık opt-in), Homebrew (Google Analytics, SSS açıklaması), Next.js (varsayılan etkin anonim istatistikler) olmak üzere üç örnek tanıtılıyor
- Analize alternatif olarak web dokümantasyonu ölçümleme, indirme sayısı ölçümleme ve kullanıcılarla doğrudan görüşme kullanılabilir
1 yorum
Hacker News yorumu
stdoutüzerinde asla animasyon göstermeyin.stderrgünlükleme, bilgi verme vb. içindir;stdoutise tty olup olmadığına bakılmaksızın her zaman yararlı çıktı sağlamalıdır.clig.deve göz atınca zamanla görüşlerin oldukça değiştiği görülüyor.