fork के बिना Bash में लिखा गया `ps aux`
(github.com/izabera)izabera/psएक Bash implementation है, जिसका मकसद ऐसी स्थिति में भी Bash के अंदरps auxके क़रीब आउटपुट की नकल करना है, जब नया process बनाया नहीं जा सकता- मुख्य स्थिति यह है कि
sshसे जुड़े machine पर भरोसेमंद bash shell तो उपलब्ध है, लेकिन बाकी सभी PID इस्तेमाल में हैं, इसलिए नया process बनाया नहीं जा सकता - README इस स्थिति को Bash/Linux ज्ञान की ज़रूरत वाली पोज़िशन के लिए एक interview question के उदाहरण के रूप में पेश करता है
- इस टूल के बारे में कहा गया है कि यह आपको “काम करने वाले
ps auxतक पहुंच होने का दिखावा” करने देता है, लेकिन यह पूरी तरह का replacement implementation होने की गारंटी नहीं देता - “हर machine और हर स्थिति में 100% काम करता है” वाला वाक्य स्पष्ट रूप से एक मज़ाकिया गारंटी के तौर पर लिखा गया है
यह प्रोजेक्ट क्या करता है
- यह
ps auxको सिर्फ Bash से लिखने वाला प्रोजेक्ट है - README का शीर्षक है “
ps auxwritten entirely in bash without ever forking” - प्रोजेक्ट की मुख्य विशेषता यह है कि रनटाइम के दौरान यह बिल्कुल भी fork नहीं करता
कल्पित स्थिति
- उदाहरण की स्थिति इस प्रकार है
- आप
sshसे machine में लॉग इन हैं - उपयोगकर्ता परिचित bash shell के अंदर है
- लेकिन बाकी सभी PID इस्तेमाल में हैं, इसलिए कोई नया process बिल्कुल भी बनाया नहीं जा सकता
- आप
- README बताता है कि ऐसी शर्तों में
ps auxजैसी क्षमता की ज़रूरत पड़ सकती है
अपेक्षित दायरा और caveat
- इस टूल को ऐसे उपयोग के लिए पेश किया गया है, जहाँ आप काम करने वाले
ps auxके होने का “कुछ हद तक दिखावा” कर सकें - README में “100% machines पर हर स्थिति में पूरी तरह काम करने की गारंटी” वाला वाक्य बढ़ा-चढ़ाकर किए गए हास्य के रूप में लिखा गया है
- इसलिए विवरण का सार यह है कि पूरी compatibility से ज़्यादा अहम बात यह है कि नया process न बना पाने वाले चरम वातावरण में सिर्फ Bash से
ps auxकी नकल की जाए
1 टिप्पणियां
Hacker News की राय
यह मज़ाक सच लगता है कि कंप्यूटर साइंस की सबसे कठिन समस्या आखिरकार alignment ठीक करना ही निकली
कई भाषाओं में column alignment functions अनगिनत बार लिखे हैं, और हर बार दर्दनाक रहा; दिमाग में यह इतना आसान लगता है कि “हर column की अधिकतम लंबाई निकालो और tab size के अगले multiple तक spaces डाल दो”
Python के f-string और padding features इस्तेमाल करने पर भी code जल्दी ही जटिल और पढ़ने में मुश्किल हो जाता है, और comments के लिए example दोबारा लिखते समय भी मैंने कई bugs ठीक किए—इतना भयानक है
इतना आम use case है तो library तो होनी ही चाहिए, और सच कहूँ तो standard library में इसका न होना हैरान करता है
तरीका यह था कि database cursor के
descriptionसे column widths और names निकालकर separator line और format string बनाई जाए, फिर rows print की जाएँ; पता नहीं कोई घातक bug छूट रहा है या नहीं, और यह कोई खास मुश्किल समस्या नहीं लगतीzip(*table)से columns को transpose करके हर column की अधिकतम लंबाई निकाल सकते हैं, फिरf"{r:<{w}}"से align करके print कर सकते हैंexample output
agony | kick | pumpजैसी aligned column widths वाली table बन जाती हैvalues के अंदर spaces होते हैं, padding spaces से होती है, कभी-कभी alignment बिगड़ जाता है और columns overflow भी हो जाते हैं
बेहतर होगा कि आपसी सहमति से column-aligned data का इस्तेमाल न करें और कोई ज्यादा सरल, human-readable format इस्तेमाल करें—सबके लिए फायदा रहेगा
अगर SSH से logged-in machine पर Bash shell तो चल रहा है, लेकिन सभी PID खत्म हो चुके हैं और नया process नहीं बनाया जा सकता, तो मैं
/proc/[pid]/filesystem खंगालकर देखूँगा कि कौन-सा process PID space खत्म कर रहा हैBash का
killshell builtin है, इसलिए/bin/killकी तरह नया process fork करने की जरूरत नहींअगर PID खत्म करने वाले child processes पैदा कर रहे parent process को ढूँढ सकें, तो उसे रोककर system पर फिर से control पाया जा सकता है
यह script भी
/procparse करती है, और इसमें pipe या$(...)substitution भी नहीं है जो नया Bash subshell बना दे, इसलिए काफी साफ-सुथरी हैइससे अलग command चलाए बिना जरूरी POSIX functions call किए जा सकते थे, इसलिए अच्छा response मिला
सीमित environment में parent process ढूँढकर मारने की तुलना में reboot के बाद recovery तेज हो सकती है, और अगर PID खत्म हो गए हैं तो बाकी चीजें भी शायद पहले से खराब हालत में होंगी
ps(){ (cd /proc;for i in [0-9]*;do echo $i: $(tr '\0' ' ' < $i/cmdline);done); }/proc/[pid]/में देखकर कौन-सा process PID space खत्म कर रहा है, यह बात सही है, लेकिन source code comments देखें तो शुरू में उम्मीद थी कि/proc/*/statusही काफी होगा, पर CPU usage जैसे values वहाँ से नहीं मिल सके[[ $cmdline ]] && exec {cmdline}>&-औरexec {cmdline}< "$dir"/cmdline || continueकैसे काम करते हैं, यह सच में जानना चाहता हूँ2011 में अमेरिका की एक काफी बड़ी tech company में SRE role के लिए interview दिया था, और उस समय SRE शब्द भी पहली बार सुना था
वह company browser-based MS Office alternative बना रही थी, और phone screening के बाद company के document editor के अंदर interviewer से call पर बात करते हुए real-time programming करनी थी
self-evaluation form में
shell scriptingऔरLinuxको high rating दी थी, इसलिए Bash मेंnetstatreplacement बनाने का task मिला, लेकिन उस समय मुझे पता नहीं था कि socket information/proc/में कहाँ और कैसे होती है, इसलिए जल्दी ही समझ गया कि यह नहीं कर पाऊँगाइसके बजाय मैंने छोटा
psऔरfuserबनाने का प्रस्ताव दिया, और उस भयानक browser-based word processor में दिया गया मेरा solution स्वीकार हो गया, जिससे onsite interview तक पहुँच गयाअब सोचता हूँ तो शायद इस exercise की motivation वाला hypothetical scenario जितना लगा था उससे ज्यादा reality में rooted था
मैं भी वहीं से शुरू करता
मैंने पहले मज़े के लिए एक interactive website बनाई थी जो SSH से logged-in हालत में नया process न बना पाने की situation explore करती है: https://oops.cmdchallenge.com
"echo *"directory की सभी files list नहीं करता"echo .* *"इस्तेमाल करना होगादूसरे steps की
"View Solutions"list देखकर यह जानना चाहता था कि कौन-कौन से other approaches possible थेIzabera #bash@libera के experts में से एक हैं
पुराने freenode के दिनों से ऐसे experts से पिछले 10 सालों में मैंने सच में बहुत कुछ सीखा है
यह काफी clean Bash है
experience के हिसाब से Bash code अक्सर खराब लिखा हुआ और inefficient होता है, लेकिन यह code उसका अच्छा counterexample लगता है
अगर आप किसी भरोसेमंद POSIX shell में हैं जिसमें Bash support नहीं है, तो क्या करेंगे?
यह Bash script POSIX-compatible नहीं है
यह script Bash 3.2 पर काम नहीं करती, लेकिन Bash 4.2 पर काम करती है
Bash 3.2 में
printf: '(': invalid format charactererror आता है, और example environmentbash-3.2-33.el5_11.4.0.1हैबेहतर use case शायद ऐसे system पर process list देखना है जहाँ procps install नहीं है
ठीक है
Bash में listener और client भी बनाए जा सकते हैं
production में recommend नहीं करूँगा