Komut Satırı Arayüzü Yönergeleri (2021)
(clig.dev)- Bu kılavuz, geleneksel UNIX ilkelerini modern biçimde güncelleyerek, insanların kullanması kolay ve otomasyon için de sağlam CLI’lar oluşturmak amacıyla hazırlanmış açık kaynaklı bir tasarım rehberidir
- İyi bir CLI insanı önceleyen şekilde çalışmalı; aynı zamanda
stdout/stderr, çıkış kodları, pipe’lar ve JSON gibi teamüllere uyarak diğer programlarla doğal biçimde birleştirilebilmelidir - Yardım, dokümantasyon, hata mesajları ve çıktı; kullanıcının bir sonraki adımı anlayabilmesini sağlamalıdır.
--help, örnekler, öneriler, ilerleme göstergeleri ve durum açıklamaları burada kilit rol oynar - Argümanlar, flag’ler, etkileşimler, yapılandırma ve ortam değişkenleri hem script’ler hem de terminal kullanımı düşünülerek tasarlanmalıdır; gizli değerleri doğrudan flag ya da ortam değişkeni üzerinden almamak daha güvenlidir
- CLI’ın adı, dağıtımı ve analiz verisi toplaması bile kullanıcının kontrol hissini ve uzun vadeli uyumluluğu zedelememelidir; teamüllerin dışına çıkılması gerektiğinde de amaç net olmalıdır
CLI tasarımının temel felsefesi
- Bu kılavuz, açık kaynaklı bir belge olarak, geleneksel UNIX ilkelerini temel alır ve modern komut satırı programları için tasarım ilkeleriyle somut yönergeler sunar
- Geçmişte komut satırı, bir script yazma platformu üzerindeki REPL’e yakın makine öncelikli bir ortamdı; ancak günümüz CLI’ları, çeşitli araçlara, sistemlere ve platformlara erişim sağlayan metin tabanlı bir UI olarak güçlü biçimde insan öncelikli bir karakter taşır
- Komut satırının eski kısıtları ve kendine özgü alışkanlıkları vardır; buna rağmen neredeyse tüm dizüstü bilgisayarlarda kullanılabilir, hem etkileşimli kullanıma hem de otomasyona uygundur ve diğer sistem bileşenlerine kıyasla daha yavaş değişir
- Bu kılavuz emacs ya da vim gibi tam ekran terminal programlarını ele almaz; belirli bir programlama diline veya araç zincirine de bağlı değildir
İnsan öncelikli ve birleştirilebilir CLI
- Bir CLI ağırlıklı olarak insanların kullandığı bir araçsa önce insanları dikkate almalıdır
- Birçok CLI programı insan kullanıcıları hedeflediği hâlde geçmişin makine merkezli etkileşim tasarımını aynen sürdürür
- Küçük programların temiz arayüzlerle birlikte çalışmasını öngören UNIX felsefesi hâlâ önemlidir
- Standart giriş, çıkış ve hata; sinyaller ve çıkış kodları gibi teamüller programlar arası birleştirmeyi mümkün kılar
- Satır tabanlı düz metin pipe ile aktarmaya uygundur; daha yapılandırılmış veri gerektiğinde JSON kullanışlıdır
- Tutarlılık, CLI öğrenme maliyetini uzun vadeli verimliliğe dönüştüren temel unsurdur
- Mevcut kalıpları izlemek, kullanıcıların komutları ve seçenekleri daha kolay tahmin etmesini sağlar
- Teamüller kullanılabilirliği zedeliyorsa dikkatli biçimde bunların dışına çıkılabilir
- İyi bir CLI ne aşırı sessiz kalmalı ne de gereğinden fazla çıktı üretmeli; kullanıcının ihtiyaç duyduğu kadar bilgi almasını sağlamalıdır
- CLI’ların GUI’lara kıyasla keşfedilebilirliğinin zayıf olduğu düşünülür; ancak kapsamlı yardım, örnekler, sonraki komut önerileri ve hata durumunda ne yapılacağını gösteren yönlendirmelerle öğrenilebilirlik artırılabilir
Etkileşimli kullanım ve sağlamlık
- Komut satırı kullanımı, tek seferlik bir çalıştırmadan çok birden fazla deneme ve düzeltmeden oluşan bir diyaloğa yakındır
- Hatalı girişlerde olası düzeltmeler önerilebilir
- Çok aşamalı işlerin ara durumu açıkça gösterilebilir
- Tehlikeli işlemlerden önce onay alınabilir
- CLI gerçekten sağlam olmalı; aynı zamanda kullanıcıya sağlam olduğu hissini de vermelidir
- Beklenmeyen girdileri zarif biçimde ele almalıdır
- Mümkün olan durumlarda işlemler idempotent olmalıdır
- Korkutucu görünen stack trace’ler varsayılan çıktıda gösterilmemelidir
- Kullanıcıya yazılımın kendi tarafında olduğu hissini veren empati önemlidir
- Buradaki esas nokta emoji kullanmak ya da aracı oyunlaştırmak değil, kullanıcının başarılı olmasını sağlayacak özeni tasarıma yansıtmaktır
- Terminal ekosisteminde çok sayıda tutarsızlık ve karmaşa vardır; ancak düşük kısıtlar sayesinde yeni icatlar mümkün olmuştur
- Mevcut kalıplar izlenmeli, ancak üretkenliği ya da kullanıcı memnuniyetini zedeleyen standartlar bilinçli olarak terk edilebilir
Mutlaka uyulması gereken temel kurallar
- Mümkünse komut satırı argümanı ayrıştırma kütüphanesi kullanılmalıdır
- Başarı durumunda çıkış kodu
0, başarısızlık durumunda ise 0 olmayan bir değer döndürülmelidir- Script’ler programın başarılı mı başarısız mı olduğunu çıkış kodu üzerinden değerlendirir
- Bir komutun ana çıktısı
stdout’a gönderilmelidir- Makinenin okuyabileceği çıktılar da varsayılan olarak
stdout’a gitmelidir ki pipe’lar düzgün çalışsın
- Makinenin okuyabileceği çıktılar da varsayılan olarak
- Günlük mesajları, hatalar gibi kullanıcıya gösterilecek mesajlar
stderr’e gönderilmelidir- Pipe ile bağlandığında bu mesajlar sonraki komutun girdisine karışmaz
Yardım tasarımı
-hve--helpverildiğinde yeterli yardım gösterilmelidir- Alt komutlar da kendi yardım metnine sahip olabilir
-hbaşka bir anlamla aşırı yüklenmemelidir
- Argüman gerektiren bir komut hiç argüman olmadan çalıştırılırsa kısa bir yardım gösterilmelidir
- Program açıklaması
- Bir veya iki örnek çağrı
- Flag açıklamaları
- Daha ayrıntılı bilgi için
--helpkullanılması gerektiğine dair yönlendirme
- Yardım metnine destek kanallarını eklemek iyi olur
- Web sitesi veya GitHub bağlantısı yaygındır
- Web dokümantasyonu varsa yardım metninden bu dokümantasyona bağlantı verilmelidir
- Alt komutlara özel sayfa veya anchor varsa doğrudan oraya bağlanmak faydalıdır
- Kullanıcılar dokümantasyondan önce örneklerden yararlanma eğilimindedir; bu yüzden yardım metninde örnekleri öne yerleştirmek iyi olur
- Karmaşık ama yaygın kullanım senaryoları önce gösterilebilir
- Örnek sayısı fazlaysa bunları ayrı bir cheatsheet komutunda veya web sayfasında tutmak uygundur
- Yardım metni kolay taranacak şekilde biçimlendirilebilir
- Kalın başlıklar okunabilirliği artırır
- Terminalden bağımsız bir yöntem kullanılmalı; kaçış karakterlerinin olduğu gibi görünmesi engellenmelidir
- Kullanıcı hatalı giriş yaptıysa ve niyeti tahmin edilebiliyorsa öneri sunulmalıdır
brew update jqkomutubrew upgrade jqkullanımını önerecek şekilde davranabilir- Önerilen komutun çalıştırılıp çalıştırılmayacağı sorulabilir, ancak zorla çalıştırmaktan kaçınılmalıdır
stdinüzerinden girdi alması gereken bir komuttastdinetkileşimli terminal ise hemen yardım gösterip çıkmalı veyastderr’e mesaj yazmalıdır
Dokümantasyon
- Yardım metni anlık bir özet ve yaygın işlere yönelik yönlendirme sunar; dokümantasyon ise aracın amacını, neyi amaçlamadığını, çalışma biçimini ve tüm kullanımını ayrıntılı biçimde ele alır
- Web tabanlı dokümantasyon sağlanmalıdır
- Aranabilir olmalı ve belirli bölümlere bağlantı verilebilmelidir
- Web dokümantasyonu en kapsamlı dokümantasyon biçimidir
- Terminal tabanlı dokümantasyon da sağlanmalıdır
- Hızlı erişilebilir
- Kurulu araç sürümüyle senkronizedir
- İnternet olmadan da çalışır
mansayfası sunmak düşünülebilir- Birçok kullanıcı önce
man mycmdkomutuna bakar gitvenpmgibi araçlarda olduğu gibihelpalt komutu üzerindenmansayfasına erişim sağlanabilir
- Birçok kullanıcı önce
Çıktı ilkeleri
- İnsan tarafından okunabilir çıktı en önemli unsurdur
- Belirli bir çıktı akışının insan tarafından okunup okunmadığını belirlemenin basit ölçütü TTY olup olmadığıdır
- Kullanılabilirliği bozmadan makine tarafından okunabilir çıktı sunulmalıdır
- Düz metin satır akışları UNIX’in evrensel arayüzüdür
- Kullanıcılar çıktıyı
grepgibi araçlara aktarınca beklendiği gibi çalışmasını bekler
- İnsan dostu çıktı makine dostu çıktıyı bozuyorsa
--plainsunulabilir- Tablo biçimli çıktıda hücreleri birden çok satıra bölmek, her kayıt için bir satır beklentisini bozabilir
--plain, betikler için üzerinde oynanmamış tablo biçimli çıktı sağlar
--jsonverilirse biçimlendirilmiş JSON çıktısı üretilmelidir- JSON, karmaşık veri yapılarını işlemeyi kolaylaştırır ve
jqile birçok JSON CLI aracıyla birlikte kullanılabilir - Web servisleri ve
curlüzerinden doğrudan pipe ile bağlamak için de uygundur
- JSON, karmaşık veri yapılarını işlemeyi kolaylaştırır ve
- Başarılı olduğunda çıktı vermeli, ancak kısa tutmalıdır
- Geleneksel UNIX komutları sorun yoksa çoğu zaman çıktı vermez, ancak bu insanlara durmuş gibi görünebilir
- Betikler için çıktısız çalışma gerekiyorsa
-qseçeneğiyle zorunlu olmayan çıktı gizlenebilir
- Durumu değiştiren komutlar, kullanıcıya neyin değiştiğini bildirmelidir
git push, yürütülen işi ve uzak dalın yeni durumunu gösteren bir örnektir
- Sistemin mevcut durumu kolayca görülebilmelidir
git status, depo durumunu ve bir sonraki çalıştırılabilecek komut ipuçlarını birlikte gösterir
- Programın iç dünyasının sınırlarını aşan işler genelde açık olmalıdır
- Kullanıcının argüman olarak vermediği dosyaları okuma veya yazma durumunda
- Uzak sunucuyla iletişim kurup dosya indirme durumunda
- Renkler bilinçli kullanılmalıdır
- Çok fazla kullanılırsa anlamı kaybolur ve okunması zorlaşır
- TTY değilse,
NO_COLORayarlanmışsa,TERM=dumbise veya--no-colorverilmişse renkler kapatılmalıdır
stdoutetkileşimli bir terminal değilse animasyon çıktısı üretilmemelidir- CI günlüklerinde ilerleme göstergelerinin ortalığı kirletmesi önlenebilir
- Çok miktarda metin çıktısı verirken
lessgibi bir pager kullanılabilir- Yalnızca
stdinveyastdoutetkileşimli terminal olduğunda kullanılması iyi olur less -FIRXmakul bir seçenek kümesi olarak kullanılabilir
- Yalnızca
Hata mesajları
- Hataları belge gibi hazırlamak, kullanıcının dokümantasyon arama süresini azaltabilir
- Öngörülebilir hatalar yakalanıp insanın anlayacağı şekilde yeniden yazılmalıdır
- Örn:
file.txtdosyasına yazılamadığı vechmod +w file.txtgerekebileceği yönünde bir yönlendirme
- Örn:
- Sinyal-gürültü oranı önemlidir
- İlgisiz çıktı ne kadar fazlaysa kullanıcının sorunu anlaması o kadar zorlaşır
- Aynı türden birden çok hata varsa tek bir açıklama başlığı altında gruplanabilir
- En önemli bilgiyi çıktının sonuna koymak iyi olur
- Kullanıcının bakışı kırmızı metne çekildiği için bu renk bilinçli olarak az kullanılmalıdır
- Beklenmeyen veya açıklanması zor bir hataysa debug/traceback bilgisi ve hata bildirme yöntemi sağlanmalıdır
- Kullanıcıyı bunaltmamak için debug günlüğü terminal yerine dosyaya yazılabilir
- Hata bildirmeyi kolaylaştırmak gerekir
- Mümkün olan bilgileri önceden doldurulmuş bir URL sağlamak buna örnektir
Argümanlar ve bayraklar
- Argümanlar konuma dayalı parametrelerdir; bayraklar ise adlandırılmış parametrelerdir
cp foo bariçinde dosya yolları argümandır-r,--recursive,--file foo.txtbayraktır
- Mümkün olduğunda argüman yerine bayraklar tercih edilmelidir
- Daha fazla yazmayı gerektirir ama anlamı nettir
- Gelecekte giriş biçimini değiştirmeyi kolaylaştırır
- Tüm bayraklar için uzun ad sağlanmalıdır
-hile--helpi birlikte bulundurmak gibi- Betiklerde anlamı açıkça göstermeye yarar
- Tek harfli bayraklar yalnızca sık kullanılan seçenekler için kullanılmalıdır
- Sonradan eklenecek bayraklar için kısa ad alanı korunabilir
- Birden çok dosyaya aynı basit işlem uygulanıyorsa birden çok argüman uygundur
rm file1.txt file2.txt file3.txtbiçimi globbing ile iyi uyum sağlar
- Farklı anlamlarda 2 veya daha fazla argüman varsa tasarımın hatalı olma olasılığı yüksektir
- İstisna olarak
cp <source> <destination>gibi yaygın ve temel işlemlerde kısalık hatırlamaya değerdir
- İstisna olarak
- Standart bayrak adları varsa bunlara uyulmalıdır
-a, --all-d, --debug-f, --force--json-h, --help-n, --dry-run--no-input-o, --output-p, --port-q, --quiet-u, --user--version
- Varsayılan değerler çoğu kullanıcı için doğru davranış olmalıdır
- Kullanıcının uygun bayrağı bulup her seferinde hatırlayarak kullanacağını varsaymak çoğu kullanıcı deneyimini kötüleştirir
- Girdi yoksa prompt ile sorulabilir, ancak prompt zorunlu olmamalıdır
- Girdiyi bayrak veya argümanla iletmenin her zaman bir yolu sunulmalıdır
stdinetkileşimli terminal değilse prompt atlanmalı ve gerekli bayrak veya argüman istenmelidir
- Tehlikeli işlemlerden önce onay alınmalıdır
- Etkileşimli çalıştırmada
yveyayesgirilmesi istenebilir - Etkileşimli olmayan çalıştırmada
-fveya--forceistenebilir - Ciddi işlemler için silinecek hedefin adı doğrudan yazdırılabilir ya da
--confirm="name-of-thing"gibi bir bayrak sunulabilir
- Etkileşimli çalıştırmada
- Dosya girdisi/çıktısı alınıyorsa
-ilestdinveyastdoutdesteklenmelidir- Geçici dosya olmadan başka komutların çıktısıyla bağlanabilir
- Mümkün olduğunda argüman, bayrak ve alt komut sırası bağımsız işlenmelidir
- Kullanıcıların önceki komutun sonuna seçenek ekleyip yeniden çalıştırması yaygındır
- Gizli değerler doğrudan bayrakla okunmamalıdır
--passworddeğeripsçıktısında veya kabuk geçmişinde görünebilir--password-filegibi dosya girdisi ya dastdindüşünülmelidir
Etkileşim
- Promptlar veya etkileşimli öğeler yalnızca
stdinTTY olduğunda kullanılmalıdır- Betiklerde veya pipe girdisi sırasında prompt çalışmayacağı için hangi bayrağın iletilmesi gerektiği hata olarak bildirilmelidir
--no-inputverilirse prompt veya etkileşimli davranış olmamalıdır- Girdi gerekiyorsa işlem başarısız olmalı ve bayrakla iletme yöntemi açıklanmalıdır
- Parola alınırken kullanıcının yazdığı değer ekrana basılmamalıdır
- Bu, terminalin echo özelliğini kapatarak yapılır
- Kullanıcının çıkabilmesi gerekir
- Ağ I/O gibi nedenlerle takılı kalmış olsa bile Ctrl-C çalışmalıdır
- SSH, tmux, telnet gibi Ctrl-C ile sonlandırılamayan sarmalayıcılarda çıkış yöntemi açıkça belirtilmelidir
Alt komutlar
- Araç yeterince karmaşıksa alt komut kümesiyle karmaşıklık azaltılabilir
- Birden çok ilişkili aracı tek bir komutta toplamak kullanımı ve keşfi kolaylaştırabilir
- Genel bayrakları, yardımı, ayarları ve depolama mekanizmalarını paylaşmak için uygundur
- Alt komutlar arasında tutarlılık gerekir
- Aynı anlam için aynı bayrak adı kullanılmalıdır
- Çıktı biçimi de benzer olmalıdır
- Birden çok seviyeli alt komutlarda tutarlı bir adlandırma sistemi kullanılmalıdır
docker container creategibi isim ve fiilden oluşan iki seviyeli kalıp yaygındır- Hem
noun verbhemverb nounmümkündür, ancaknoun verbdaha yaygın görünür
- Belirsiz veya birbirine benzeyen komut adlarından kaçınılmalıdır
updateveupgradebirlikte varsa kafa karıştırıcı olabilir
Sağlamlık
- Kullanıcının girdiği tüm veriler doğrulanmalı
- Hatalı veri gelebileceği için hızlıca kontrol edilmeli ve anlaşılır bir hatayla durulmalı
- Hızlı olmaktan çok tepki verebilirlik daha önemlidir
- 100 ms içinde kullanıcıya bir şey çıktısı vermek iyidir
- Ağ isteğinden önce bile bir mesaj yazdırarak takılmış gibi görünmesi engellenmeli
- Uzun süren işler için ilerleme durumu gösterilmeli
- Bir süre çıktı olmazsa program bozulmuş gibi görünür
- İlerleme göstergesi uzun süre aynı yerde kalırsa, kalan süre tahmini veya animasyonla çalışmanın sürdüğü gösterilebilir
- Paralel işlem mümkünse yapılmalı, ancak dikkatli olunmalı
- Paralel işlerin ilerlemesini shell’de göstermek zordur; çıktıların birbirine karışması kafa karıştırır
docker pulliçindeki birden fazla ilerleme çubuğu, neler olduğunu gösteren bir örnektir- Normal çalışmada günlükler ilerleme çubuğunun arkasına gizlense bile, hata olduğunda günlükler çıktılanmalı ki hata ayıklama mümkün olsun
- Ağ işlemlerinin zaman aşımı olmalı
- Zaman aşımı yapılandırılabilir olmalı ve makul bir varsayılan değere sahip olmalı
- Hata sonrası kurtarma mümkün olmalı
- Geçici bir hatadan sonra
<up>ve<enter>ile yeniden çalıştırıldığında kaldığı yerden devam edebilmeli
- Geçici bir hatadan sonra
- Mümkünse crash-only yaklaşımı iyidir
- Hata veya kesinti durumunda hemen çıkılabilir, temizlik bir sonraki çalıştırmaya bırakılabilir
- Kullanıcılar aracı beklenmedik şekillerde kullanabilir
- Betiklerle sarabilir, kararsız internette kullanabilir, aynı anda birden fazla örnek çalıştırabilir veya test edilmemiş ortamlarda çalıştırabilir
Geleceğe dönük uyumluluk
- Alt komutlar, argümanlar, bayraklar, yapılandırma dosyaları ve ortam değişkenlerinin hepsi arayüzdür; uzun süre çalışır kalacak şekilde korunmalıdır
- Mümkün olan değişiklikler eklemeli olmalı
- Mevcut bir bayrağın davranışını bozmak yerine yeni bir bayrak eklenebilir
- Eklemeli olmayan bir değişiklik gerekiyorsa önceden uyarılmalı
- Artık önerilmeyen bir bayrak kullanıldığında ilerideki değişiklik bildirilmeli ve şimdiden kullanılabilecek geleceğe uyumlu yöntem de anlatılmalı
- İnsanlara yönelik çıktının değişmesi genelde sorun değildir
- Kullanıcılar, betiklerde kararlı çıktı için
--plainveya--jsonkullanmaya yönlendirilmeli
- Kullanıcılar, betiklerde kararlı çıktı için
- Her şeyi yakalayan alt komutlardan kaçınılmalı
- Bilinen bir alt komut değilse otomatik olarak
rungibi ele alan bir yaklaşım, ileride yeni bir alt komut eklendiğinde mevcut kullanımları bozabilir
- Bilinen bir alt komut değilse otomatik olarak
- Alt komutlar için keyfi kısaltmalara izin verilmemeli
installiçiniveyainskabul edilirse, ilerideiile başlayan başka bir komut eklemek zorlaşır- Takma adlar açık ve kararlı tutulmalı
- Komutun 20 yıl sonra da aynı şekilde çalışıp çalışmayacağı düşünülmeli
- Dış internet bağımlılıkları değişip kaybolduğunda komutu durduran bir saatli bomba yaratılmamalı
Sinyaller ve kontrol karakterleri
- Kullanıcı Ctrl-C, yani INT sinyali gönderdiğinde mümkün olduğunca hızlı çıkılmalı
- Temizlik işine başlamadan önce hemen bir şey söylenmeli
- Temizlik kodu için zaman aşımı konulmalı
- Uzun süren temizlik sırasında Ctrl-C tekrar girilirse temizlik atlanabilmeli
- Docker Compose, kapanış sırasında Ctrl-C’ye bir kez daha basılırsa konteynerlerin hemen zorla durdurulabileceğini bildirir
- Program, önceki temizlik işinin çalıştırılmadığı bir durumda başlatılabileceğini varsaymalı
Yapılandırma ve ortam değişkenleri
- Yapılandırma yöntemi özgüllük, kararlılık ve karmaşıklığa göre değişmeli
- Her çalıştırmada sık değişen ayarlar için bayraklar uygundur
- Kullanıcıya, projeye veya makineye göre değişen nispeten kararlı ayarlar için bayraklar ve ortam değişkenleri uygundur
- Proje içinde tüm kullanıcılar için kararlı ayarlar için sürüm kontrolüne alınan, komuta özel yapılandırma dosyası uygundur
- XDG Base Directory Specification izlenmesi iyidir
~/.configgibi genel amaçlı yapılandırma konumlarını destekleyerek ana dizindeki dotfile artışını azaltma amacı taşır
- Kendi programınızın yapılandırması olmayan dosyaları otomatik değiştiriyorsanız kullanıcı onayı alınmalı ve tam olarak ne yapıldığı anlatılmalı
- Mevcut sistem yapılandırma dosyasına ek yapmak yerine yeni bir yapılandırma dosyası oluşturmak daha iyidir
- Yapılandırma önceliği yüksekten düşüğe doğru uygulanmalı
- Bayraklar
- Çalışan shell’in ortam değişkenleri
- Proje düzeyi yapılandırma
- Kullanıcı düzeyi yapılandırma
- Sistem geneli yapılandırma
- Ortam değişkenleri, komutun çalıştırıldığı bağlama göre değişen davranışlar için uygundur
- Ortam değişkeni adları, en yüksek taşınabilirlik için yalnızca büyük harf, rakam ve alt çizgi kullanmalı; rakamla başlamamalı
- Değerler mümkünse tek satır olmalı
- Çok satırlı değerler
envkomutuyla birlikte kullanıldığında kullanılabilirlik sorunları çıkarır
- Çok satırlı değerler
- Yaygın kullanılan adlar gelişigüzel sahiplenilmemeli
- POSIX standart ortam değişkenleri listesi referans alınabilir
- Mümkün olduğunda genel amaçlı ortam değişkenleri kontrol edilmeli
NO_COLOR,FORCE_COLORDEBUGEDITORHTTP_PROXY,HTTPS_PROXY,ALL_PROXY,NO_PROXYSHELLTERM,TERMINFO,TERMCAPTMPDIRHOMEPAGERLINES,COLUMNS
- Uygun olduğunda
.enviçinden ortam değişkenleri okunabilir- Belirli bir dizinde çalışırken neredeyse hiç değişmeyen değişkenler için yararlıdır
.env, resmi yapılandırma dosyasının yerine geçmez- Çoğu zaman kaynak kontrolüne kaydedilmez
- Yalnızca string türü vardır
- Düzeninin bozulması kolaydır
- Kodlama sorunları çıkması kolaydır
- Hassas kimlik bilgileri ve anahtar malzemesi içermesi kolaydır
- Gizli değerler ortam değişkenlerinden okunmamalı
- Ortam değişkenleri süreçler, günlükler,
docker inspect,systemctl showvb. üzerinden açığa çıkabilir - Gizli bilgiler kimlik bilgisi dosyaları, pipe’lar,
AF_UNIXsoketleri, gizli bilgi yönetim servisleri veya başka IPC yöntemleriyle alınmalı
- Ortam değişkenleri süreçler, günlükler,
Adlandırma, dağıtım ve analiz toplama
- CLI program adları kullanıcılar tarafından sık yazıldığı için basit ve hatırlanması kolay olmalı
- Çok genel olursa diğer komutlarla çakışabilir veya kullanıcıların kafasını karıştırabilir
- Adlarda küçük harf ve gerektiğinde tire kullanılması iyidir
curliyi bir addır;DownloadURLise iyi olmayan bir örnektir
- Ad kısa olmalı, ancak çok kısa adlar
cd,ls,psgibi çok yaygın yardımcı programlara yakışır - Yazması kolay bir ad olmalı
- Docker Compose’un ilk adının
plumolduğu, tek elle yazması garip olduğu içinfigolarak değiştirildiği bir örnek vardır
- Docker Compose’un ilk adının
- Mümkünse tek bir binary olarak dağıtılmalı
- Tek binary zorsa, platformun varsayılan paket yükleyicisi kullanılarak kaldırması kolay bir yöntemle dağıtılmalı
- Dile özel araçlar, örneğin kod linter’ları, kullanıcının ilgili dil yorumlayıcısına sahip olduğunu varsayabilir
- Kaldırması kolay olmalı
- Kurulumdan hemen sonra kaldırmak isteme durumu yaygın olduğundan, kaldırma yönergesini kurulum yönergesinin altına koymak iyidir
- Kullanım metrikleri aracı iyileştirmeye yardımcı olabilir, ancak CLI kullanıcıları kendi ortamlarını kontrol ettiklerini varsayar
- Onay almadan kullanım veya çökme verileri gönderilmemeli
- Nelerin toplandığı, neden toplandığı, ne kadar anonimleştirildiği, nasıl anonimleştirildiği ve ne kadar süre saklandığı açıkça belirtilmeli
- İdeal olan opt-in’dir; varsayılan toplama olan opt-out seçilirse web sitesinde veya ilk çalıştırmada açıkça bildirilmeli ve kolayca kapatılabilmeli
- Analiz toplamanın alternatifleri de değerlendirilebilir
- Web dokümantasyonu ölçümlenebilir
- İndirmeler ölçümlenebilir
- Kullanıcılarla doğrudan konuşulabilir; dokümantasyon ve depolarda geri bildirim ve özellik istekleri teşvik edilebilir
1 yorum
Hacker News yorumları
“Günümüzde çoğu kişi komut satırının ne olduğunu bile bilmiyor” sözü doğru, ama TFA'nın ölçüt aldığı 1980'lerde de durum aynıydı
Fark şu: Bugün komut satırını bilen ve kullanabilen kişi sayısı tarihteki en yüksek seviyede; en azından tek haneli, belki de çift haneli katlar kadar arttığı için buna CLI'nin altın çağı denebilir
Küresel durum ve bağımlılıklar akıl yürütmeyi zorlaştırıyor, sonunda hata ayıklamayı ve performans optimizasyonunu da güçleştiriyor
500 satır, 1.000 satır, 5.000 satır, 10.000 satır, bazen 50 bin satırlık kodu ayrı çalışacak şekilde dışarı çıkarınca birçok şey çok daha netleşiyor
Doğru yapılırsa Functional Core, Imperative Shell yapısını da teşvik edebilir; çünkü Unix felsefesine uygun bir komut satırında yan etkisiz davranışlar çok, yan etkili davranışlar az olmalı
Kötü bir karar verilmeden hemen önceki sistem durumunu üretip çıktılayan küçük komutlar oluşturabilirsiniz; bunlar üretim ortamında da fiilen güvenle çalıştırılabilir
Böylece bus factor kapsamına girmesi gereken kişilere de bu araçları devredip sürece dahil etmek kolaylaşır
Amazon'un ücra bir uygarlık köyündeki birinin terminal hakkında ne düşündüğü konuyla ilgili değil
Niceliği büyümüş bir şeyin nitel değişimini değerlendirmek için orana bakmak gerekir; yalnızca mutlak sayıya bakarsanız doğru ama anlamsız bir cümle elde edersiniz
Örneğin bugün caz dinleyicilerinin mutlak sayısı, türün kültürel altın çağındakinden fazla olabilir; ama bu cazın daha popüler olmasından değil, müzik dinleyen insanların genel olarak artmasından kaynaklanır
Buna bakarak cazın ABD'de altın çağındakinden daha önemli ve etkili olduğunu söylemek zordur
Gerçek bir değişiklik yapmadan hangi işlemlerin gerçekleşeceğini önceden gösteren
--dry-runseçeneğinin de dikkate alınmasını isterdimBir aracı öğrenirken ya da geri alınması zor işlemleri çalıştırmadan önce karmaşık seçenekleri ve dosya glob'larını doğru kullanıp kullanmadığınızı kontrol etmek için gerçekten faydalı
--dry-runyapmak ve gerçek çalıştırma için--executebayrağı istemek daha iyiOnsuz ne yapardım bilmiyorum; birçok kez tamamen berbat etmek üzere olduğum durumdan beni kurtardı
--commitgeçirilmesini tercih ediyorumGeri alınamayan ya da geri alınması zor işler yapan script'ler için bu yaklaşım bana daha güvenli geliyor
Geliştirdiğim araçlarda bunu nasıl tasarlamam gerektiği konusunda kafam karışık
Veri almak için API çağıran bir durumda bunu nasıl dry run yapabileceğimi bilmiyorum
Sahte bir örnek ve sahte çıktı mı vermem gerekiyor?
do_thing.py | dry-runBunu, istemde “işlem sürecini adım adım açıkla” diye sormak gibi düşünebilirsiniz
Standart çıktı etkileşimli terminal değilse animasyon göstermeyin demek yetmez; stdout'ta asla animasyon gösterilmemeli
TFA genel olarak iyiydi, ama stderr ile stdout arasındaki farkı açıklayacak bir bölüm ararken bunu yapmadığını görünce üzüldüm
stderr yalnızca hataların değil, log'ların ve bilgilendirici çıktının tamamının gitmesi gereken yerdir; terminalse animasyon da koyabileceğiniz alandır
stdout kullanışlı gerçek çıktı olmalı ve terminal olup olmamasından bağımsız olarak tutarlı kalmalı
Örneğin
echo foo | mysed 's/oo/aa/' | catiçindemysed'in stdout'ufaaolmalı; stderr'e ise sürüm bilgisi ya da bulunan içerikler gibi log'lar gitmeliSırf gerçek çıktıyı almak için grep ile araçla boğuşmak istemiyorum;
| catkısmını çıkarınca davranışın değişmesi yüzünden hata ayıklamanın zorlaşmasını da istemiyorum--helpistendiyse stdout'a gitmeli; log istendiyse log'lar da stdout'a gitmeliİstenmeyen bilgiyse doğru yer stderr'dir
Zamanı geri alabilseydik stdin, stdout, stdext gibi adlar verilseydi insanların bu geleneği izleme olasılığı olurdu gibi geliyor
Ama adı stderr olduğu için geliştiriciler makul biçimde bunun “hata raporlama için” olduğunu düşünüyor ve hata değilse stdout'a koyuyor
Yine de program yapısı açısından bu yaklaşım daha iyi; başta daha kafa karıştırıcı olsa da çıktı üzerinden daha faydalı işler yapılabildiği için kazançlı
Rengin de bilgi sayılmasının zor olduğunu düşünüyorum
“Netlik sağladığı yerlerde sembol ve emoji kullanın” tavsiyesinden lütfen kaçınılsın
Örnek verilen yubikey-agent, GitHub README'lerinde ve oyuncu kullanıcı arayüzlerinde sevmediğim şeyleri aynen gösteriyor
Teknik olarak semboller ve emojiler farklı terminallerde farklı render edilerek mesajı kafa karıştırıcı hale getirebilir
Estetik açıdan da oyunculuk ve neşelilik toleransı kişiden kişiye çok değiştiği için çok ölçülü, gerçekten ne yaptığınızı bildiğiniz durumlarda kullanılmalı
Renkli terminal çıktısını da seviyorum; emojiler de renkli olduğu için durumun genel resmini hızlıca kavramaya yardımcı oluyor
Sözdizimi vurgulamayı da seviyorum; olmayınca kodu okumak bana çok daha zor geliyor
Herkes böyle değil; kendi zevkimin varsayılan olmasını beklemediğim gibi, zıt zevk de varsayılan olarak dayatılmamalı
Seven de var, sevmeyen de; bu yüzden varsayılan kapalı olsun ama kullanıcı seçebilsin
Örneğin bir başarı, bir de hata için olan yeterlidir
Ayrıca emojinin ilettiği bilgi mutlaka metinle de yinelenmeli
CLI Guidelines'ı ilk gördüğümde de o bölümde okumayı bırakmıştım
Bu kez geri kalanını da okudum ve genel olarak oldukça iyiydi
Bazı CLI’ların
awsgibi çok büyük olduğu için iç içe yapıya ihtiyaç duyduğunu anlıyorum, ama iç içe CLI içinde ilerlemek gerçekten sinir bozucuÇoğu uygulamanın help içinde tüm seçenekleri dökmesi ve benim de
lessile ihtiyacım olanı bulmamı sağlaması daha iyiBu TUI, istenirse kullanılan saf bir UI/UX; seçilen ayarları ayrı bir üretilen dosyaya veya fonksiyona aktarıyor
O dosya veya fonksiyon her zaman terminalden doğrudan çağrılabiliyor ve TUI’de kullanılan tüm seçenekleri ve yardım metinlerini de sunuyor
Böylece betiklerde de kullanılabiliyor ve farklı yetkinlik seviyelerindeki kullanıcılar için faydalı oluyor
Gerekli alt komutu biliyorsanız seçenekleri yalnızca gerekenlere indirmesi oldukça yararlı; bilmiyorsanız acı verici olabilir
Büyük seçenek listelerinde grep ile aramak da zor, bu yüzden bir denge gerekiyor
mansayfalarının görevi değil mi?--helpçıktısını üst komutun içine açarak yerleştirmek yardımcı olabilirÖrneğin
git stash --helpkomutunun, her maddeyi içerengit stashyardımını olduğu gibi göstermesi gibi“Geleneksel olarak UNIX komutları, öncelikle başka programlar tarafından kullanılacağı varsayımıyla yazıldı” açıklaması doğru değil
Başlangıçta esas olarak oturum açma shell’i içinde etkileşimli kullanım amaçlanmıştı
stdout’a çıktı üreten programlar (
ls,cat,find,tty,who,date) ve sessiz metin filtreleri (tr,grep,cut,uniq,sort,wc) vardı; o dönemde tek satırlık komutlarla temel bilişim işleri yapılabiliyorduKarmaşık programlar C ile yazılıyordu;
sedve AWK gibi alana özgü diller ortaya çıktıktan sonra, yoğun dize işleme yapan bazı programlar shell’e taşındıShell düzgün bir programlama ortamı değildir ve hiçbir zaman bu amaçla tasarlanmamıştır
Günümüzde ikisini de Python ya da Lua ile yapmak çoğu zaman daha iyi olabilir, ama shell ve C en yaygın kurulu olanlar
sh,bash,ksh,cshayrışması bunun iyi bir örneğiStandart POSIX araç takımını, çeşitli shell dillerinin standart kütüphanesi olarak görmek bence oldukça makul
Mevcut Unix komut satırı bir yandan “inanılmaz derecede faydalı”, diğer yandan tasarım gereği bozuk
Aşağıdakini C veya Rust ile yazmanın ne kadar süreceğini düşününce faydası açık:
curl -sS https://go.dev/doc/devel/release | html2text | grep -o -P '\bgo\d+\.\d+\.\d+\b' | sort -V | uniq | tail -1Ama neden tasarım gereği bozuk olduğunu görmek için https://news.ycombinator.com/item?id=29747034 adresine bakabilirsiniz
Sorun, komut satırı arayüzünün hem insanlar için okunabilir hem de makineler için okunabilir olması gerekmesi ve bunu çözmenin standart bir yolunun olmaması
İnsanların ve makinelerin aynı anda okuyabilmesi sorununa aslında standart bir çözüm olabilirdi
Apple, masaüstü UI’nin görsel soyutlama anlamını somutlaştırmak için Human Interface Guidelines’ı oluşturdu
Ama komut satırını Apple tasarımcıları gibi düşünen insanlar değil, “tembellik, sabırsızlık ve kibir erdemdir; istediğimi en az kodla nasıl ifade ederim” diye düşünen insanlar yaptı
O dönem için yanlış bir tercih de değildi ve her bayt önemliydi; fakat o tasarım kararı bugün artık yerinden oynatılamayan bir araç zincirine gömülmüş durumda
Bugünkünden daha iyi bir şey elde etmek için POSIX araç zincirinden fiilen vazgeçmek gerekecek gibi görünüyor; mevcut temel üzerine keşfedilebilir ve kavramsal olarak tutarlı bir UX inşa etmeyi hayal etmek zor
Aynı anda bile farklı çıktılar sunmayı mümkün kılan pek çok yöntem var
Ancak herkesin uyduğu bir standart olmalı; iş tam da bu noktada karmaşıklaşıyor
lsuygulamalarının çok azı dosya adlarını satır sonu yerine NUL karakteriyle bitirmeye izin veriyorsa, çözüm o kadar açık görünüyor ki bir şeyi kaçırıyor gibiyimShell arayüzü bunu bir nedenle reddediyor mu?
--jsongibi makine tarafından okunabilir çıktı modlarıdır“Gizli değerleri ortam değişkenlerinden okumayın” deyip kimlik bilgisi dosyaları, pipe’lar, AF_UNIX soketleri, gizli değer yönetim servisleri ve diğer süreçler arası iletişim yöntemlerini öneriyor; bunların arasında hangisinin en kullanışlı ve taşınabilir olduğunu merak ediyorum
Gizli değer yönetim servislerinin yalnızca işte mi kullanıldığını, kişisel projelerde de kullanılıp kullanılmadığını da merak ediyorum
Komut satırında gizli değerlerle çalışma konusunu biraz daha derinlemesine ele alan yazı https://smallstep.com/blog/command-line-secrets/ adresinde
Kimlik bilgisi dosyaları basit ve taşınabilir bir seçenek
Dosyaların zaten bir izin modeli var ve harici servislere ya da tescilli API’lere bağımlı değiller
Bir program kimlik bilgisi dosyası kabul ediyorsa systemd credentials ile de uyumlu olur
systemd credentials, şifrelenmemiş kimlik bilgisi dosyalarından daha güvenlidir; şifrelenir ve TPM’e de bağlanabilir, ancak kimlik bilgilerini kullanan yazılımın TPM’i kendi başına desteklemesi gerekmez
Örneğin mbsync(https://isync.sourceforge.io/mbsync.html) IMAP kimlik doğrulama parolasını sağlamanın kabaca üç yolunu sunar
Parola ayarlanmazsa çalıştırma sırasında bir istem çıkar; yapılandırma dosyasına düz metin parola da koyabilirsiniz ama bu, paylaşım için elverişsizdir
Ayrıca parolayı getirecek bir komut ayarlanabildiğinden, işlem pass(1)(https://www.passwordstore.org/) gibi bir parola yöneticisine veya etkileşimli grafik bir isteme devredilebilir
Belgeleri iyi hazırlanmıştır; ek bir şey geliştirmeye gerek kalmadan kolayca ayarlanabilir
Doppler(https://Doppler.com) veya AWS Secrets Manager(https://aws.amazon.com/secrets-manager/) gibi gizli değer yöneticileri, gizli değerleri güvenli bir yerde koruma altına alma ve bunların açığa çıkmasını en aza indirme avantajına sahiptir
Hatta şirket içi geliştiricilere karşı bile görünürlüğü azaltabilir; bu da kolayca önlenebilecek veri sızıntılarını engellemeye yardımcı olur
Bu tür sızıntılar tüm şirketi riske atabilir ve giderek daha yaygın hale geliyor
İlgili yazılar: Command Line Interface Guidelines - https://news.ycombinator.com/item?id=38053692 - Ekim 2023, 1 yorum
Command Line Interface Guidelines - https://news.ycombinator.com/item?id=31651161 - Haziran 2022, 1 yorum
Command Line Interface Guidelines - https://news.ycombinator.com/item?id=25492119 - Aralık 2020, 5 yorum
Panodan yapıştırılan dizgenin sonunda satır sonu karakteri varsa bazı terminallerin komutu otomatik olarak çalıştırması gerçekten sinir bozucu
Kişisel olarak komut satırı arayüzlerinin böyle yapmaması gerektiğini düşünüyorum
bind 'set enable-bracketed-paste on'kullanabilirsinizRahatsız ediyorsa kapatılabilir
Gerekirse çok satırlı da olabilir ve çalışması için Enter’a basmanız gerekir
Fish shell’in varsayılanları çoğu zaman mantıklıydı; istem dışında özellikle özelleştirmek istediğim bir yer henüz bulamadım
Denediklerimin çoğunda pano içeriğinden satır sonlarını kaldırma seçeneği vardı
#yazıp sonra yapıştırınSatır sonu yorumlansa bile tüm satır yorum olur, böylece güvenlidir; gerçekten çalıştırmadan önce satırın başındaki
#karakterini silmeniz yeterli