Linux & UX

Her terminalin başında bir alıntı

Fikir, kolay görünecek kadar küçüktü. Çoğu küçük fikir gibi, uygulaması beklediğimden çok daha fazla özen istedi.

Ramazan Yavuz
Ramazan Yavuz ·

Her yeni terminalin başında günlük bir alıntı istiyordum. Bunda teknik olarak ilginç bir şey yok. curl ve halka açık bir alıntı API'siyle tek satırlık bir shell hook'unda 30 saniyede yapabilirsiniz, ki ben de yaptım, ve bir hafta içinde üç sorunum oldu. Bazen API yavaş olduğu için terminal açmak iki saniye boyunca bloke oldu. Uçaklarda hiç alıntım olmadı. Tek satırım, farklı makinelerimdeki farklı shell init'leri arasında hayatta kalamadı. Bu yüzden herald'ı yaptım: aynı fikrin sıkıcı yoldan yapılmışı – küçük bir daemon, bir CLI, bir systemd zamanlayıcısı ve bir önbellek dosyası. Bu parçaların hiçbiri zekice değil. İlginç olan iş, hangi parçaların var olması gerektiğine karar vermekti.


Naif shell hook'u her terminal açtığınızda bir ağ isteği yapar. Günde bir kez değişen bir bilgi için günde düzinelerce istek. API ücretsiz ve operatör cömerttir, ama bu kabalık. İstek başarısız da olabilir, yavaş da: ya shell'i bekletirsiniz, ki kötüdür, ya da arka plana atarsınız ve alıntı promptunuzun ortasında belirir, ki daha kötüsüdür. Ve alıntı, gün boyunca her terminalde aynı olmalı. Üç terminal açıp üç farklı alıntı görürsem, deneyim yanlıştır. Alıntının küçük, sakin bir tutarlılık olması gerekir.

Çekmeyi gösterimden ayırmak üçünü de düzeltir. Çekme bir zamanlayıcıyla, arka planda, bir önbellek dosyasına yapılır. Gösterim önbellek dosyasını okur ve hızlı, çevrimdışıya dost ve shell'ler arası tutarlıdır.


Bir systemd zamanlayıcısı (herald-refresh.timer) varsayılan olarak her üç saatte bir çalışır ve /var/cache/herald/today.json'a bir JSON nesnesi yazar. Çekme, 1.5 saniyelik bir zaman aşımı ile zenquotes.io'ya gider. Başarısız olursa, paketle birlikte gelen yaklaşık 30 küratörlü alıntıdan oluşan yerel bir havuza geri düşer, böylece araç her zaman çevrimdışı çalışır. Terminal selamı önbelleği okur. Login MOTD'si önbelleği okur. Hiçbiri ağ işi yapmaz. İkisi de hızlı, ikisi de tutarlı, ikisi de deterministik.

Yenileme aralığı saat cinsinden yapılandırılabilir. Günde bir için sudo herald set-refresh 24, haftada bir için sudo herald set-refresh 168, çevrimiçi çekmeyi tamamen devre dışı bırakıp yalnızca yerel havuzu döndürmek için sudo herald set-refresh 0. sudo herald refresh hemen tetikler. Zamanlayıcı, unit dosyasının tek satırlık bir override'ıdır, akıllı zamanlama mantığı yok.


Her interaktif shell'in başında bir alıntı göstermek, SSH girişinde göstermekle aynı sorun gibi geliyor. Değil. Ubuntu'daki interaktif shell'ler login akışı üzerinden /etc/profile.d/'i sourceler, ama yeni bir GUI terminal sekmesi genellikle bir login shell değildir, bu yüzden /etc/profile.d/ source edilmez. Kullanıcının ~/.bashrc'sine, profile.d snippet'ini açıkça sourceler bir işaretçi blok eklemek zorundaydım. Bu bashrc bloğu herald'a aittir ve sudo herald terminal off onu kaldırır.

SSH, konsol ve ekran yöneticisi girişleri update-motd sistemini kullanır, yani /etc/update-motd.d/'ye bir script bırakırsınız. Bu, Debian ve Ubuntu'da Suggests olan, Recommends olmayan update-motd paketini gerektirir. Yani sadece dizüstü kullanıcıları onu varsayılan olarak çekmez. CLI, MOTD'yi olmayan bir sistemde etkinleştirirseniz çalışma zamanında uyarır.

İki yüzey de varsayılan olarak kapalıdır. sudo herald terminal on ve sudo herald motd on onları bağımsız olarak değiştirir. Bağımsızlıkları önemli: alıntıyı her yeni terminalde istiyorum ama SSH banner'ımda istemiyorum. Başka biri tam tersini isteyebilir.


Herald üçüncü taraf bir hizmetten çeker. İçeriği kontrol etmiyorum. zenquotes zevksiz bulduğum bir alıntı sunarsa, birinin terminalinde belirir, ve README bu konuda nettir. Çevrimiçi çekmeyi set-refresh 0 ile devre dışı bırakın eğer yalnızca paketteki havuza güvenmek istiyorsanız.

Çevrimiçi çekme, varsayılan olarak açık ve net bir opt-out'la – tersi yerine. Çevrimdışı havuz tek başına çabuk bayatlar: 30 alıntının dönmesi bir hafta içinde tanıdık gelmeye başlar, ve çevrimiçi yenileme tazeliği koruyan şeydir. Ödün, kurulumun ne yaptığı konusunda yüksek sesli olması ve ağı kapatmanın tek bir komut olmasıdır.


Tekrar tekrar geri döndüğüm şey, küçük yardımcı programların belirsiz olmayan başarısızlık modlarını ciddiye aldığınızda içlerinde ne kadar karmaşıklık saklı olduğu. herald'ın ilk versiyonu 20 satır shell'di. Sevkiyat versiyonu bir daemon, bir zamanlayıcı, bir önbellek, iki entegrasyon yolu, bir yedek havuz ve bir CLI'dır. Bunların hiçbiri abartı değil. Karmaşıklık, shell başlatmanın önemli olması, ağ hatalarının yaşanması, login banner'larının ve shell selamlarının farklı tesisat olması, ve dizüstümde çalışıp başkasının headless sunucusunda kırılan bir özelliğin gerçekten bir özellik olmaması nedeniyle var.

herald'da yeni bir algoritma yok. İlginç iş, ne zaman çekileceğine, ne zaman gösterileceğine, ağ başarısız olduğunda ne yapılacağına ve iki gösterim yüzeyini nasıl senkronize tutulacağına karar vermekti. İyi çözülmüş sıkıcı sorunlar, insanların makinelerinde yaşayan herhangi bir yazılımın büyük kısmıdır. Sabah terminaliniz sizi bir Knuth alıntısıyla selamlıyor ve bunu hiç düşünmek zorunda kalmıyorsanız, herald işini yapıyor demektir.