Fork Olmadan Bash ile Yazılmış ps aux
(github.com/izabera)izabera/ps, yeni süreç oluşturmanın mümkün olmadığı durumlarda bile Bash içindeps auxçıktısına yakın bir çıktıyı taklit etmek için geliştirilmiş bir Bash uygulamasıdır- Temel koşul,
sshile bağlanılan bir makinede güvenilen bir bash shell bulunması, ancak diğer PID’lerin tamamı kullanımda olduğu için yeni süreç oluşturulamamasıdır - README, bu durumu Bash/Linux bilgisi gerektiren pozisyonlar için bir mülakat sorusu örneği olarak sunar
- Bu aracın, “çalışan bir
ps aux’a erişiminiz varmış gibi davranmanızı” sağladığı ifade edilir; eksiksiz bir alternatif uygulama olduğu garanti edilmez - “Her makinede ve her durumda %100 çalışır” ifadesi açıkça şaka amaçlı bir garanti olarak kullanılmıştır
Nasıl bir proje
ps aux’un yalnızca Bash ile yazılmış bir projesidir- README başlığı “
ps auxwritten entirely in bash without ever forking” şeklindedir - Projenin temel özelliği, çalışma sırasında hiç fork yapmamasıdır
Varsayılan durum
- Örnek durum şöyledir
- Makineye
sshile bağlısınız - Kullanıcı, aşina olduğu bir bash shell içindedir
- Ancak diğer PID’lerin tamamı kullanımda olduğundan hiç yeni süreç oluşturulamamaktadır
- Makineye
- README, bu koşullarda
ps auxbenzeri bir işleve ihtiyaç duyulabileceğini anlatır
Beklenebilecek kapsam ve caveat
- Bu araç, çalışan bir
ps auxvarmış gibi “kinda sorta pretend” etmenizi sağlayan bir şey olarak tanıtılır - README’deki “makinelerin %100’ünde, her durumda kusursuz çalışır, garanti” ifadesi abartılı bir mizah olarak kullanılmıştır
- Dolayısıyla açıklamadaki ana nokta, tam uyumluluktan ziyade, yeni süreç oluşturmanın mümkün olmadığı uç bir ortamda yalnızca Bash ile
ps aux’u taklit etmesidir
1 yorum
Hacker News yorumları
Bilgisayar bilimindeki en zor problemin eninde sonunda hizalamayı tutturmak olduğu şakası gerçekten yerini buluyor
Çeşitli dillerde sütun hizalama fonksiyonlarını sayısız kez yazdım; her seferinde acı vericiydi. Kafanın içinde “her sütunun maksimum uzunluğunu bul, sekme boyutunun bir sonraki katına kadar boşluk ekle” gibi basit görünüyor
Python'ın f-string ve padding özelliklerini kullansan bile kod hızla karmaşıklaşıp okunması zorlaşıyor; yorum için örneği yeniden yazarken bile birkaç bug düzeltecek kadar berbat
Bu kadar yaygın bir kullanım için elbette bir kütüphane vardır diye düşünüyorsun; açıkçası standart kütüphanede olmaması şaşırtıcı
Veritabanı imlecinin
descriptionalanından sütun genişliklerini ve adlarını çıkarıp ayırıcı çizgi ile format string'i oluşturuyor, sonra satırları yazdırıyor. Gözden kaçırdığım ölümcül bir bug var mı bilmiyorum; özellikle zor bir problem gibi görünmüyorzip(*table)ile sütunları ters çevirip her sütunun maksimum uzunluğunu bulabilir, ardındanf"{r:<{w}}"ile hizalayarak yazdırabilirsinizÖrnek çıktı,
agony | kick | pumpgibi sütun genişlikleri hizalanmış bir tablo olurDeğerlerin içinde boşluk oluyor, boşlukla doldurulmuş oluyor, bazen hizalama kayıyor ve sütunlar taşıyor
Bence aramızda anlaşıp sütun hizalı veri kullanmasak, daha basit ve insanın okuyabileceği bir format kullansak herkes için daha iyi olur
SSH ile girdiğiniz bir makinede Bash kabuğu yaşıyor ama tüm PID'ler tükenmiş ve yeni süreç oluşturulamıyorsa, hangi sürecin PID alanını tükettiğini görmek için
/proc/[pid]/dosya sistemini kurcalardımBash'in
killkomutu kabuk yerleşiğidir;/bin/killgibi yeni bir süreç fork etmek gerekmezPID'leri tüketen çocuk süreçleri doğuran ebeveyn süreci bulabilirseniz onu durdurup sistemin kontrolünü geri alabilirsiniz
Bu script de
/proc'u ayrıştırıyor; yeni bir Bash alt kabuğu oluşturabilecek pipe ya da$(...)substitution da yok, bu yüzden epey temizBöylece ayrı bir komut çalıştırmadan gereken POSIX fonksiyonlarını çağırabildiğiniz için iyi tepki almıştım
Kısıtlı bir ortamda ebeveyn süreci bulup öldürmektense yeniden başlatıp toparlanmak daha hızlı olabilir; PID'ler bittiyse başka şeylerin de çoktan kötü durumda olma ihtimali yüksek
ps(){ (cd /proc;for i in [0-9]*;do echo $i: $(tr '\0' ' ' < $i/cmdline);done); }/proc/[pid]/içinde hangi sürecin PID alanını tükettiğine bakmak doğru; ancak kaynak kod yorumlarına göre başta yalnızca/proc/*/status'un yeterli olmasını ummuşlar, fakat CPU kullanımı gibi değerler oradan alınamıyormuş[[ $cmdline ]] && exec {cmdline}>&-veexec {cmdline}< "$dir"/cmdline || continueifadelerinin nasıl çalıştığını gerçekten merak ediyorum2011'de ABD'deki epey büyük bir teknoloji şirketinde SRE rolü için mülakata girmiştim; o zaman SRE terimini de ilk kez duymuştum
Şirket, tarayıcı tabanlı bir MS Office alternatifi yapıyordu; telefon elemesinden sonra şirketin belge düzenleyicisi içinde mülakatçıyla görüşürken gerçek zamanlı programlama yapmanız gerekiyordu
Öz değerlendirme formunda
shell scriptingveLinuxiçin yüksek puan verdiğimden Bash ilenetstatalternatifi yapma görevi aldım, ama o zaman soket bilgilerinin/proc/içinde nerede ve nasıl durduğunu bilmiyordum; kısa sürede yapamayacağıma karar verdimBunun yerine küçültülmüş bir
psvefuseryapmayı önerdim; o berbat tarayıcı tabanlı kelime işlemcide sunduğum çözüm kabul edildi ve onsite mülakata kadar gittimŞimdi düşününce, bu alıştırmanın motivasyonu olan varsayımsal senaryo sandığımdan daha fazla gerçekliğe dayanıyor olabilir
Ben olsam ben de oradan başlardım
SSH ile bağlıyken yeni süreç oluşturulamayan bir durumu keşfetmeye yarayan interaktif bir web sitesini eskiden eğlence için yapmıştım: https://oops.cmdchallenge.com
"echo *"dizindeki tüm dosyaları listelemez"echo .* *"kullanmak gerekirDiğer aşamaların
"View Solutions"listelerine bakıp başka hangi yaklaşımların mümkün olduğunu görmek isterdimIzabera, #bash@libera'nın ustalarından biri
Eski freenode günlerinden beri bu ustalardan son 10 yılda gerçekten çok şey öğrendim
Bu oldukça temiz Bash
Deneyimlerime göre Bash kodu genelde kötü yazılmış ve verimsiz oluyor; bu kod öyle olmayan iyi bir örnek gibi görünüyor
Bash desteği olmayan güvenilir bir POSIX kabuğundaysanız ne yapmalı?
Bu Bash script'i POSIX uyumlu değil
Bu script Bash 3.2'de çalışmıyor ama Bash 4.2'de çalışıyor
Bash 3.2'de
printf: '(': invalid format characterhatası veriyor; örnek ortambash-3.2-33.el5_11.4.0.1Daha iyi kullanım alanı, procps kurulu olmayan sistemlerde süreç listesini görmek olabilir
Fena değil
Bash ile listener ve client da yapılabilir
Pratikte tavsiye etmem