बैश में आवश्यक कमांड की जाँच करते समय और इंटरफ़ेस के बारे में बात करते हुए
नमस्ते, मैं अक्षम हूँ।
मैंने अपने काम के आखिरी दिन पूरे किए, उसी कार्यस्थल की एक लड़की से चॉकलेट मिली, सेवानिवृत्ति से ठीक पहले मुझे याकिनिकु (जापानी बारबेक्यू) के लिए ले जाया गया, और मैंने 25 साल से नेटवर्क इंजीनियर रहे एक व्यक्ति के साथ उनके पिछले और वर्तमान होम नेटवर्क वातावरण के बारे में बात करते हुए और अपने खुद के होम सर्वर सेटअप के बारे में बात करते हुए अच्छा समय बिताया।
मुझे लगता है कि मैंने अपनी अपरिपक्वता के बावजूद जितना हो सका उतना किया, लेकिन मैं एक ऐसा व्यक्ति हूँ जिसमें बहुत सारी कमियाँ हैं, इसलिए मुझे खेद है।
मुझे हर दिन लगता है कि शेल स्क्रिप्ट बहुत शक्तिशाली हैं।
बेशक, इसकी कम पोर्टेबिलिटी एक समस्या है, क्योंकि यह फ़ंक्शन-शैली में नहीं लिखा जा सकता है, जैसे कि csh जो अब FreeBSD के डिफ़ॉल्ट शेल के रूप में मौजूद है, और इस समस्या से इनकार नहीं किया जा सकता है।
हालांकि, मेरा मानना है कि शेल स्क्रिप्ट की वास्तविक शक्ति इंटरफ़ेस को संभालने में आसानी में निहित है।
C और शेल स्क्रिप्ट इंटरफ़ेस
उदाहरण के लिए, मान लीजिए कि आप शेल स्क्रिप्ट में echo का उपयोग इस प्रकार करते हैं।
echo "test"
यह C भाषा में मानक आउटपुट के बराबर है।
#include <stdio.h>
int main() {
const char *message = "test";
// मानक आउटपुट पर संदेश आउटपुट करें
fprintf(stdout, "%s\n", message);
return 0;
}
यदि आप इसे मानक त्रुटि आउटपुट पर आउटपुट करना चाहते हैं, तो आप इसे इस प्रकार रीडायरेक्ट करेंगे।
echo "testerr" 1>&2
और C भाषा के मामले में, यह इस प्रकार है।
#include <stdio.h>
int main() {
const char *message = "testerr";
// मानक त्रुटि आउटपुट पर संदेश आउटपुट करें
fprintf(stderr, "%s\n", message);
return 0;
}
इसके अलावा, अधिकांश GNU/Linux कमांड निष्पादन विफलताओं के लिए वापसी मानों को पिछले अग्रदूतों के कारण कुशलता से डिज़ाइन किया गया है, जिससे परीक्षण की स्थिति आसान हो जाती है, और यदि इसे स्क्रिप्टिंग भाषा के रूप में उपयोग किया जाता है तो यह काफी प्रभावी होता है।
हालांकि, समस्या यह है कि इसका लाभ केवल उन वातावरणों में उठाया जा सकता है जहाँ शेल स्क्रिप्ट का उपयोग किया जा सकता है।
भले ही आप अन्य भाषाओं में समान कोड लिखते हैं, इसकी बहुमुखी प्रतिभा प्रभावी होती है, लेकिन कमांड एक ऐसी प्रणाली के रूप में काम करते हैं जो भाषा में पुस्तकालयों के बराबर होती है, और मुझे लगता है कि यही कारण है कि इसे कम बहुमुखी कहा जाता है।
हालांकि, मुझे लगता है कि फ़ाइल डिस्क्रिप्टर को इतनी सरलता से संचालित करने की क्षमता बहुत शक्तिशाली है।
else भी केवल दो पाइपों को जोड़ने जैसा है।
*लिखने के बाद मुझे लगा, कड़ाई से कहें तो यह else नहीं है ^^;
यह केवल एक else की तरह काम करता है जब वापसी मान 0 के अलावा कुछ और होता है।
$ curl aa || echo "wtf"
curl: (6) Could not resolve host: aa
wtf
कितना अच्छा होता अगर मुझे मिडिल स्कूल में ही इतनी उपयोगी चीज़ों के बारे में पता चल जाता।
काश हर वेबसाइट शेल स्क्रिप्ट सीखने के लिए और अधिक अवसर प्रदान करती।
या बल्कि, अब जब मुझे याद है, तो उस समय GNU/Linux का जापानी वातावरण काफी कठिन था, और मुझे याद है कि जापानी इनपुट के लिए भविष्य कहनेवाला रूपांतरण अव्यावहारिक स्तर पर था, इसलिए शायद Chrome OS के प्रसार के कारण OSS जापानी इनपुट फला-फूला, जिससे आज की सुविधा मिली।
मुझे यह भी याद है कि जब मैं मिडिल स्कूल में था, तो मेरे एक सनकी दोस्त ने Ubuntu के साथ एक ThinkPad चाहा था और मैंने उसे सेट अप किया था...
तो, कमांड चेक कैसे करें?
मैं सोच रहा था कि बैश शेल स्क्रिप्ट में कमांड चेक लिखते समय क्या कोई स्मार्ट और पढ़ने में आसान तरीका है।
हालांकि, एक सरणी से लूप प्रोसेसिंग के लिए for का उपयोग करके पास करना निश्चित रूप से सुविधाजनक है, जो मूल रूप से स्मार्ट है, लेकिन जब आप सरणी भंडारण के लिए सिंटैक्स देखते हैं।
#!/bin/bash
cmds=(aa bb cc)
for i in ${cmds[@]}; do
command -v $i 1> /dev/null || echo "Please install $i"
done
इसे () के साथ एक सरणी के रूप में cmds में संग्रहीत किया जाता है, और सरणी को ${cmds[@]} के साथ विस्तारित किया जाता है।
लेकिन अगर कमांड की संख्या बढ़ती है और आप उन्हें cmds=() में जोड़ते रहते हैं, तो आपको यह महसूस होने लगता है कि क्या उन्हें यहाँ लिखने की कोई आवश्यकता है?
अन्य भाषाओं में, निर्भरता की जानकारी Cargo.toml, deno.json, go.mod, Gemfile, और अक्सर नापसंद किए जाने वाले requirements.txt जैसी फ़ाइलों में पैक की जाती है।
अगर ऐसी कोई फ़ाइल हो जिसमें यह सब एक साथ हो तो यह सुविधाजनक होगा।
तो, मैंने इसे इस तरह से करने की कोशिश की।
#!/bin/bash
cat ./cmd | xargs which 1> /dev/null || echo "Please install cmd"
और cmd फ़ाइल कैसी दिखती है?
$ cat cmd
ls
pwd
cargo
वास्तव में, मैं command कमांड के साथ जांच करना चाहता था, लेकिन command एक शेल आंतरिक कमांड के रूप में काम करता है और इसे xargs में पास नहीं किया जा सका।
$ which command
which: no command in (/home/haturatu/.rbenv/bin:/home/haturatu/.rbenv/shims:/home/haturatu/.deno/bin:/home/haturatu/.cargo/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/opt/android-sdk/platform-tools:/var/lib/flatpak/exports/bin:/usr/lib/jvm/default/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl:/usr/lib/plan9/bin:/home/haturatu/.local/bin:/home/haturatu/.local/bin:/home/haturatu/Android/Sdk/cmdline-tools/tools/bin:/home/haturatu/Android/Sdk/platform-tools:/home/haturatu/Android/Sdk/emulator:/home/haturatu/Android/Sdk/tools:/home/haturatu/Android/Sdk/tools/bin:/home/haturatu/Android/Sdk/cmdline-tools/tools/bin:/home/haturatu/Android/Sdk/platform-tools:/home/haturatu/Android/Sdk/emulator:/home/haturatu/Android/Sdk/tools:/home/haturatu/Android/Sdk/tools/bin:/home/haturatu/.npm-global/bin:/home/haturatu/go/bin)
यदि मैं गलत हूँ तो मुझे क्षमा करें, लेकिन जब xargs के साथ पास किया जाता है, तो यह xargs प्रक्रिया के रूप में चलता है, जो निष्पादित bash प्रक्रिया से एक अलग प्रक्रिया है, इसलिए मुझे लगता है कि इसे पहचाना नहीं जा सकता है।
इसलिए, मैं which के साथ विफल हुए कमांड को Please install cmd में पास नहीं कर सकता, लेकिन which का त्रुटि आउटपुट उस बिंदु से पहले ही प्रदर्शित हो जाता है, इसलिए मुझे लगा कि इसकी आवश्यकता नहीं है।
*लिखने के बाद मुझे लगा, क्या xargs /bin/bash command -v काम करेगा...।
इन कमांडों को एक अलग फ़ाइल में रखने का एक और फायदा है।
आप इस फ़ाइल से एक साथ इंस्टॉल कर सकते हैं।
cat cmd | xargs -I {} sudo pacman -S --noconfirm {}
apt के मामले में, -y विकल्प के साथ भी ऐसा ही संभव है।
तो, मैं इसे एक विचार के रूप में छोड़ रहा हूँ, भले ही मैं वास्तव में इसका उपयोग करूँ या न करूँ।
फिर मिलेंगे। शुभकामनाएँ। (यह सिर्फ एक भ्रम है कि मैंने साल के अंत के लेख के बाद से कुछ लेख लिखे हैं)