Computer >> कंप्यूटर ट्यूटोरियल >  >> प्रोग्रामिंग >> Ruby

रूबी के साथ अपने खुद के लिनक्स टूल्स बनाएं: एक व्यावहारिक गाइड

आइए मिलकर एक प्रोजेक्ट बनाते हैं!

ps, top और netstat जैसे लिनक्स टूल्स बहुत उपयोगी हैं।

ये आपके सिस्टम के बारे में ढेर सारी जानकारी देते हैं।

  • लेकिन ये काम कैसे करते हैं?
  • ये अपनी सारी जानकारी कहाँ से प्राप्त करते हैं?
  • हम अपने खुद के टूल्स बनाने के लिए इसका उपयोग कैसे कर सकते हैं?

इस पोस्ट में हम मिलकर तीन लोकप्रिय लिनक्स टूल्स को फिर से बनाएंगे।

आपको एक साथ दोहरा लाभ मिलेगा: कुछ रूबी ट्रिक्स सीखेंगे और उपयोगी लिनक्स ज्ञान भी प्राप्त करेंगे! 🙂

स्टेटस जानकारी ढूंढना

तो आइए उस सवाल का जवाब देने की कोशिश करते हैं कि ये सभी टूल्स अपनी जानकारी कहाँ से पाते हैं।

जवाब है proc फाइलसिस्टम में!

यदि आप /proc डायरेक्टरी के अंदर देखें, तो यह आपके कंप्यूटर पर किसी अन्य डायरेक्टरी की तरह ही डायरेक्टरीज़ और फाइलों का एक समूह लगेगा।

ये असली फाइलें नहीं हैं, यह केवल लिनक्स कर्नेल का उपयोगकर्ताओं को डेटा उजागर करने का एक तरीका है।

यह बहुत सुविधाजनक है क्योंकि इन्हें सामान्य फाइलों की तरह माना जा सकता है, जिसका अर्थ है कि आप इन्हें किसी विशेष टूल के बिना पढ़ सकते हैं।

लिनक्स की दुनिया में बहुत सी चीज़ें इसी तरह काम करती हैं।

यदि आप एक और उदाहरण देखना चाहते हैं तो /dev डायरेक्टरी पर एक नज़र डालें।

अब जब हम समझ गए हैं कि हम किससे निपट रहे हैं, तो आइए /proc डायरेक्टरी की सामग्री पर एक नज़र डालते हैं…

1 10 104 105 11 11015 11469 11474 11552 11655 

यह सिर्फ एक छोटा सा नमूना है, लेकिन आप जल्दी से एक पैटर्न देख सकते हैं।

वे सभी संख्याएं क्या हैं?

ठीक है, पता चला है कि ये PID (प्रोसेस आईडी) हैं।

प्रत्येक एंट्री में एक विशिष्ट प्रोसेस के बारे में जानकारी होती है।

यदि आप ps चलाते हैं तो आप देख सकते हैं कि कैसे हर प्रोसेस से एक PID जुड़ा होता है:

PID TTY TIME CMD 15952 pts/5 00:00:00 ps 22698 pts/5 00:00:01 bash 

इससे हम यह निष्कर्ष निकाल सकते हैं कि ps क्या करता है: यह केवल /proc डायरेक्टरी पर पुनरावृति करता है और जो जानकारी पाता है उसे प्रिंट करता है।

आइए देखते हैं कि उन नंबर वाली डायरेक्टरीज़ में से एक के अंदर क्या है:

attr autogroup auxv cgroup clear_refs cmdline comm cpuset cwd environ exe fd 

यह सिर्फ जगह बचाने के लिए एक नमूना है, लेकिन मैं आपको पूरी सूची देखने के लिए प्रोत्साहित करता हूं।

यहां कुछ दिलचस्प एंट्रीज़ हैं:

एंट्री विवरण
comm प्रोग्राम का नाम
cmdline इस प्रोसेस को लॉन्च करने के लिए इस्तेमाल की गई कमांड
environ पर्यावरण चर जिनके साथ यह प्रोसेस शुरू किया गया था
status प्रोसेस स्टेटस (रनिंग, स्लीपिंग…) और मेमोरी उपयोग
fd डायरेक्टरी जिसमें फाइल डिस्क्रिप्टर्स होते हैं (खुली फाइलें, सॉकेट…)

अब जब हम यह जानते हैं तो हम कुछ टूल्स लिखना शुरू कर सकते हैं!

चल रहे प्रोग्राम्स को कैसे सूचीबद्ध करें

आइए /proc के तहत सभी डायरेक्टरीज़ की सूची प्राप्त करके शुरू करते हैं।

हम इसे Dir क्लास का उपयोग करके कर सकते हैं।

उदाहरण:

Dir.glob("/proc/[0-9]*") 

ध्यान दें कि मैंने एक नंबर रेंज का उपयोग कैसे किया, कारण यह है कि /proc के तहत अन्य फाइलें हैं जिनकी हमें अभी परवाह नहीं है, हम केवल नंबर वाली डायरेक्टरीज़ चाहते हैं।

अब हम इस सूची पर पुनरावृति कर सकते हैं और दो कॉलम प्रिंट कर सकते हैं, एक PID के साथ और दूसरा प्रोग्राम नाम के साथ।

उदाहरण:

pids = Dir.glob("/proc/[0-9]*")
puts "PID\tCMD"
puts "-" * 15
pids.each do |pid|
  cmd = File.read(pid + "/comm")
  pid = pid.scan(/\d+/).first
  puts "#{pid}\t#{cmd}"
end 

और यह आउटपुट है:

PID CMD
---------------
1 systemd
2 kthreadd
3 ksoftirqd/0
5 kworker/0
7 migration/0
8 rcu_preempt
9 rcu_bh
10 rcu_sched 

अरे, ऐसा लगता है हमने अभी ps बना लिया! हां, यह मूल से सभी फैंसी विकल्पों का समर्थन नहीं करता, लेकिन हमने कुछ काम करने वाला बना लिया।

कौन सुन रहा है?

आइए अब netstat को दोहराने की कोशिश करते हैं, यह आउटपुट कैसा दिखता है ( -ant फ्लैग्स के साथ)।

Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 127.0.0.1:5432 0.0.0.0:* LISTEN
tcp 0 0 192.168.1.82:39530 182.14.172.159:22 ESTABLISHED 

हमें यह जानकारी कहाँ मिल सकती है? यदि आपने /proc के अंदर कहा तो आप सही हैं! अधिक विशिष्ट होने के लिए आप इसे /proc/net/tcp में पा सकते हैं।

लेकिन एक छोटी सी समस्या है, यह netstat आउटपुट की तरह बिल्कुल नहीं दिखता!

0: 0100007F:1538 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1001 0 9216
1: 2E58A8C0:9A6A 9FBB0EB9:0016 01 00000000:00000000 00:00000000 00000000 1000 0 258603 

इसका मतलब है कि हमें रेगुलर एक्सप्रेशन्स के साथ कुछ पार्सिंग करने की आवश्यकता है। अभी के लिए आइए केवल लोकल एड्रेस और स्टेटस के बारे में चिंता करें।

यहां वह रेगुलर एक्सप्रेशन है जो मैं लेकर आया:

LINE_REGEX = /\s+\d+: (?<local_addr>\w+):(?<local_port>\w+) \w+:\w+ (?<status>\w+)/ 

यह हमें कुछ हेक्साडेसिमल मान देगा जिन्हें हमें दशमलव में बदलने की आवश्यकता है। आइए एक क्लास बनाते हैं जो हमारे लिए यह करेगा।

class TCPInfo
  def initialize(line)
    @data = parse(line)
  end

  def parse(line)
    line.match(LINE_REGEX)
  end

  def local_port
    @data["local_port"].to_i(16)
  end

  # हेक्स को नियमित IP नोटेशन में बदलें
  def local_addr
    decimal_to_ip(@data["local_addr"].to_i(16))
  end

  STATUSES = {
    "0A" => "LISTENING",
    "01" => "ESTABLISHED",
    "06" => "TIME_WAIT",
    "08" => "CLOSE_WAIT"
  }

  def status
    code = @data["status"]
    STATUSES.fetch(code, "UNKNOWN")
  end

  # इसके बारे में ज्यादा चिंता न करें। यह कुछ बाइनरी गणित है।
  def decimal_to_ip(decimal)
    ip = []
    ip << (decimal >> 24 & 0xFF)
    ip << (decimal >> 16 & 0xFF)
    ip << (decimal >> 8 & 0xFF)
    ip << (decimal & 0xFF)
    ip.join(".")
  end
end 

बाकी केवल एक सुंदर टेबल फॉर्मेट में परिणाम प्रिंट करना है।

require 'table_print'
tp connections 

उदाहरण आउटपुट:

STATUS | LOCAL_PORT | LOCAL_ADDR
------------|------------|--------------
LISTENING | 5432 | 127.0.0.1
ESTABLISHED | 39530 | 192.168.88.46 

हां, यह जेम बहुत बढ़िया है!

मुझे बस इसके बारे में पता चला और लगता है कि मुझे फिर से ljust / rjust के साथ उलझना नहीं पड़ेगा 🙂

मेरे पोर्ट का उपयोग करना बंद करो!

क्या आपने कभी यह संदेश देखा है?

Address already in use - bind(2) for "localhost" port 5000 

उम्म…

मुझे आश्चर्य है कि कौन सा प्रोग्राम उस पोर्ट का उपयोग कर रहा है।

आइए पता लगाते हैं:

fuser -n tcp -v 5000
PORT USER PID ACCESS CMD
5000/tcp rubyguides 30893 F.... nc 

अरे, तो ये है हमारा अपराधी!

अब हम इस प्रोग्राम को रोक सकते हैं अगर हम नहीं चाहते कि यह चलता रहे और वह हमारा पोर्ट खाली कर देगा। fuser प्रोग्राम को कैसे पता चला कि इस पोर्ट का उपयोग कौन कर रहा था?

आपने सही अनुमान लगाया!

/proc फाइलसिस्टम फिर से।

वास्तव में, यह उन दो चीजों को जोड़ता है जिन्हें हमने पहले ही कवर किया है: प्रोसेस सूची के माध्यम से चलना और /proc/net/tcp से सक्रिय कनेक्शन पढ़ना।

हमें बस एक अतिरिक्त कदम की आवश्यकता है:

खुले पोर्ट की जानकारी का PID से मिलान करने का एक तरीका खोजें।

यदि हम /proc/net/tcp से प्राप्त होने वाले TCP डेटा को देखें, तो वहां PID नहीं है। लेकिन हम इनोड नंबर का उपयोग कर सकते हैं।

“एक इनोड एक डेटा संरचना है जिसका उपयोग फाइलसिस्टम ऑब्जेक्ट को दर्शाने के लिए किया जाता है।” – विकिपीडिया

हम इनोड का उपयोग करके मिलान करने वाली प्रोसेस कैसे ढूंढ सकते हैं? यदि हम एक प्रोसेस के fd डायरेक्टरी के तहत देखते हैं जिसे हम जानते हैं कि उसके पास एक खुला पोर्ट है, तो हमें इस तरह की एक लाइन मिलेगी:

/proc/3295/fd/5 -> socket:[12345] 

कोष्ठक के बीच की संख्या इनोड नंबर है। तो अब हमें बस सभी फाइलों पर पुनरावृति करनी है और हम मिलान करने वाली प्रोसेस ढूंढ लेंगे।

इसे करने का एक तरीका यहां दिया गया है:

x = Dir.glob("/proc/[0-9]*/fd/*").find do |fd|
  File.readlink(fd).include? "socket:[#{socket_inode}]"
rescue nil
end
pid = x.scan(/\d+/).first
name = File.readlink("/proc/#{pid}/exe")
puts "Port #{hex_port.to_i(16)} in use by #{name} (#{pid})" 

उदाहरण आउटपुट:

Port 5432 in use by /usr/bin/postgres (474) 

कृपया ध्यान दें कि आपको इस कोड को रूट के रूप में या प्रोसेस मालिक के रूप में चलाने की आवश्यकता होगी।

अन्यथा आप /proc के अंदर प्रोसेस विवरण पढ़ने में सक्षम नहीं होंगे।

निष्कर्ष

इस पोस्ट में आपने सीखा कि लिनक्स वर्चुअल /proc फाइलसिस्टम के माध्यम से बहुत सारा डेटा उजागर करता है। आपने यह भी सीखा कि /proc के तहत डेटा का उपयोग करके ps, netstat और fuser जैसे लोकप्रिय लिनक्स टूल्स को कैसे फिर से बनाया जाए।

नीचे न्यूज़लेटर की सदस्यता लेना न भूलें ताकि आप अगली पोस्ट से न चूकें। 🙂


  1. अपने दम पर रहने की लागत की गणना करने के लिए टेक टूल्स अपने दम पर रहने की लागत की गणना करने के लिए टेक टूल्स

    जैसे-जैसे देश भर के विश्वविद्यालयों में स्कूल के पहले दिन निकट आ रहे हैं, अधिक छात्र इस तथ्य से अवगत हो रहे हैं कि वे जल्द ही अपने रहने के खर्चों के थोक के लिए जिम्मेदार होंगे। हममें से जिन्होंने छलांग लगाने और अपने दम पर बाहर जाने से पहले अपने संभावित रहने की लागत का अनुमान लगाने की कोशिश की, वे शा

  1. Ruby मेथड्स समझाए गए: आसानी से कस्टम फंक्शन्स बनाएं Ruby मेथड्स समझाए गए: आसानी से कस्टम फंक्शन्स बनाएं

    मेथड्स को कैसे परिभाषित करें Ruby प्रोग्रामिंग भाषा में कई शक्तिशाली बिल्ट-इन मेथड्स हैं जिनका आप उपयोग कर सकते हैं, लेकिन आप अपने खुद के भी बना सकते हैं। कैसे? आप def कीवर्ड का उपयोग करके अपनी खुद की इंस्टेंस मेथड को परिभाषित कर सकते हैं। यहाँ सिंटैक्स है: def gimme_bacon puts Bacon plz. end यहा

  1. SUSE Studio: अपना खुद का कस्टम लिनक्स वितरण बनाएं SUSE Studio: अपना खुद का कस्टम लिनक्स वितरण बनाएं

    SUSE Studio एक Novell-प्रायोजित सेवा है जो हर किसी को, मैं दोहराता हूँ हर किसी को, कुछ धैर्य और अपने वेब ब्राउज़र के अलावा कुछ भी उपयोग करके openSUSE और वेरिएंट के अपने कस्टम फ्लेवर बनाने की अनुमति देती है। अविश्वसनीय लगता है? यह है। SUSE Studio अभूतपूर्व रूप से सफल और उपयोगी Kiwi इमेजिंग सिस्टम क