Ubuntu-OSX संगतता के लिए #! / Bin / sh या #! / Bin / bash का उपयोग करें और उपयोग में आसानी & POSIX


18

मुझे पता है कि मैं वांछित शेल को लागू करने के लिए स्क्रिप्ट की पहली पंक्ति के रूप में उपयोग कर सकता हूं।

चाहेंगे #!/bin/shअगर सभी यूनिक्स सिस्टम के साथ संगतता के एक परम आवश्यकता है की सिफारिश की जा?

मेरे मामले में एकमात्र ओएस 'मुझे परवाह है कि उबंटू (डेबियन) और ओएसएक्स हैं। यह देखते हुए, क्या मैं उपयोग कर सकता हूं #!/bin/bashऔर आश्वस्त हो सकता हूं कि यह दोनों प्रणालियों पर काम करेगा?
यह भी आदेशों के लिए अधिक आधुनिक और स्पष्ट वाक्यविन्यास के साथ लिपियों का उपयोग करना आसान बना देगा? क्या #!/bin/shPOSIX का उपयोग करना भी संबंधित है?


1
शायद ध्यान देने योग्य बात यह है कि कई विकृतियों ने विलय /binऔर शुरू कर दिया है /usr/bin। परिणामस्वरूप, #!/usr/bin/env <shname>इन दिनों पोर्टेबिलिटी के लिए उपयोग करना बेहतर है ।
हालोसगॉस्ट

जवाबों:


15

शुरुआत के लिए, यदि आप यह अनुमान लगा सकते हैं कि बैश प्रीइंस्टॉल्ड है (जो, मेरी जानकारी के लिए आपके द्वारा सूचीबद्ध सभी सिस्टम पर मामला है), संगत होने के लिए निम्न हैशबैंग का उपयोग करें:

#!/usr/bin/env bash

यह bashकॉन्फ़िगर करता है जो कुछ भी कॉन्फ़िगर किया जाना है, कोई फर्क नहीं पड़ता कि यह अंदर है /binया नहीं /usr/local/bin

जबकि एक विस्तृत श्रृंखला (AIX, Solaris, कई BSD जायके सहित) की अधिकांश प्रणालियों पर, bashविभिन्न स्थानों envमें समाप्त हुई , हमेशा में समाप्त हुई /usr/bin/env। ट्रिक, मेरी नहीं है, लेकिन बैश कुकबुक के लेखक की है।

वैसे भी, बैश आपको कुछ "आधुनिक" सुविधाओं का उपयोग करने की अनुमति देगा जो आपके जीवन को आसान बनाते हैं।

उदाहरण के लिए डबल कोष्ठक:

[[ -f "/etc/debian_version" ]] && echo "This is a Debian flavor"

पारंपरिक शेल बोलियों में रहते हुए आपको इसका सहारा लेना होगा:

test -f "/etc/debian_version" && echo "This is a Debian flavor"

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

आप वाक्यविन्यास के $((2**10))साथ काफी सुविधाजनक अभिव्यक्तियों जैसे या अन्य अंकगणितीय अभिव्यक्तियों का उपयोग कर सकते हैं $((expression))

उपधाराओं के लिए बैकटिक्स का उपयोग करना ठीक है, भले ही थोड़ा पुराना हो। लेकिन $(command ...)इनवोकेशन की नेस्टिंग क्षमताएं अधिक सुविधाजनक होती हैं क्योंकि आपको अलग-अलग सबस्क्रिप्शन स्तरों पर कई चीजों से बचना नहीं होगा।

ये हैं, लेकिन कुछ चीजें जो बैश आपको पारंपरिक आम POSIX shसिंटैक्स पर देती हैं।

लेकिन यदि आप शेल पर अधिक शक्ति चाहते हैं (न केवल लिपियों में), तो एक नज़र भी डालें zsh


बैश एक बहुत ही उपयोगी उपकरण है, लेकिन सावधानी बरतते हुए सेवाओं को शुरू करने के लिए इसका उपयोग न करें जो बैश स्क्रिप्टिंग बग के लिए असुरक्षित हो सकते हैं, जैसे access.redhat.com/security/cve/CVE-2014-6271shऐसे कार्यों के लिए छड़ी ।
रिक -777

1
रिक -777 कि भेद्यता बहुत अधिक थी और मेरी राय में आपकी टिप्पणी FUD है। यदि कोई सिस्टम सर्विस बैश के तहत चलती है तो यह उस बग के लिए किसी भी तरह से कमजोर नहीं है। यह केवल उस बग के लिए असुरक्षित है, अगर यह दूरस्थ उपयोगकर्ताओं को FastCGI की तरह एक या एक से अधिक पर्यावरण चर तक सीधी पहुंच की अनुमति देता है, और तब भी केवल बैश के अनपेक्षित संस्करणों पर ही अनुमति देता है। से shजुड़े सिस्टम पर bash, भेद्यता का उपयोग करके कम नहीं किया जाएगा sh
स्कोर_उंडर

11

डेबियन और उबंटू /bin/shमें dash, जो कि POSIX-compliant खोल है। यदि आप निर्दिष्ट करते हैं #!/bin/sh, तो आपको अपनी स्क्रिप्ट में खुद को POSIX स्टेटमेंट तक सीमित करना होगा। (इससे होने वाला लाभ dashतेजी से शुरू होता है bash, इसलिए आपकी स्क्रिप्ट कम समय में अपना काम कर सकती है।)

कई (सबसे?) अन्य Linux सिस्टम पर, /bin/shहै bash, क्यों कई लिपियों में लिखी जाती हैं, जो #!/bin/shउनकी कुटिया लाइन भले ही वे का उपयोग के रूप में bashएक्सटेंशन।

यदि आप bashएक्सटेंशन का उपयोग करना चाहते हैं , तो निर्दिष्ट करने के लिए सभी प्रणालियों पर सबसे सुरक्षित दृष्टिकोण है #!/bin/bash; इस तरह से आप अपनी निर्भरता को स्पष्ट रूप से बता रहे हैं bash। आपको डेबियन और उबंटू पर ऐसा करने की आवश्यकता है। एक अतिरिक्त बोनस के रूप में, जब /bin/sh bashकुछ एक्सटेंशनों को डी-एक्टिवेट करना शुरू किया जाता है ( विवरण के लिए bashपोसिक्स मोड का विवरण देखें); इसलिए #!/bin/bashइसका पूरा लाभ प्राप्त करने के लिए निर्दिष्ट करना आवश्यक है bash

OS X पर /bin/bashभी उपलब्ध है, और /bin/shहै bash। निर्दिष्ट #!/bin/bashकरने से वहां भी ठीक काम होगा।


5

हां, OSX और Linux दोनों साथ आएंगे /bin/bash। आपको पूरी तरह से सुरक्षित होना चाहिए। हालाँकि, यह POSIX नहीं है । POSIX शेल /bin/shअधिकांश (सभी?) सिस्टम पर है और यह सबसे पोर्टेबल तरीका है और POSIX संगत होने का एकमात्र तरीका है।

ध्यान दें कि जबकि कई सिस्टम पर /bin/shअंक के लिए bash, दूसरों पर यह अलग गोले को इंगित कर सकते हैं। यह dashउदाहरण के लिए डेबियन और उबंटू के लिए एक सहानुभूति है । इसके अलावा, यहां तक ​​कि अगर /bin/shएक लिंक है bash, तो शेल का व्यवहार तब बदल जाता है जब इसे sh( man bashजोर, जोर से ) कहा जाता है :

यदि बैश को नाम श के साथ लगाया जाता है, तो यह पोस मानक के अनुरूप होने के साथ-साथ यथासंभव समीप के ऐतिहासिक संस्करणों के स्टार्टअप व्यवहार की नकल करने की कोशिश करता है। जब इंटरकाइव टाइव लॉगइन शेल, या नॉन-इंटरेक्टिव शेल - the एल्गिन विकल्प के रूप में आमंत्रित किया जाता है, तो यह पहले उस क्रम में / etc / प्रोफाइल और ~ / .profile से कमांड को पढ़ने और निष्पादित करने का प्रयास करता है। इस व्यवहार को बाधित करने के लिए --noprofile विकल्प का उपयोग किया जा सकता है। जब नाम श के साथ एक इंटरैक्टिव शेल के रूप में आमंत्रित किया जाता है, तो बैश वेरिएबल ईएनवी की तलाश करता है, अगर यह है तो इसके मूल्य का विस्तार करता है
पढ़ने और निष्पादित करने के लिए फ़ाइल के नाम के रूप में विस्तारित मूल्य को परिभाषित, उपयोग करता है। चूंकि शेल का आह्वान किया गया है, श के रूप में किसी भी अन्य स्टार्टअप फ़ाइलों से आदेशों को पढ़ने और निष्पादित करने का प्रयास नहीं करता है, - Theffile विकल्प का कोई प्रभाव नहीं है। नाम श के साथ लगाया गया एक गैर-इंटरैक्टिव शेल किसी अन्य स्टार्टअप फ़ाइलों को पढ़ने का प्रयास नहीं करता है। जब श के रूप में आमंत्रित किया जाता है, तो स्टार्टअप फ़ाइलों को पढ़ने के बाद बैश पॉज़िक्स मोड में प्रवेश करता है।


2

यदि "सभी यूनिक्स सिस्टम" के साथ संगतता एक पूर्ण आवश्यकता है - और यदि यह नहीं है, तो आप एक शेल स्क्रिप्ट क्यों लिख रहे हैं? - तो, ​​हाँ, आप का उपयोग किया जाना चाहिए #! /bin/sh, क्योंकि बैश कहीं भी स्थापित होने की गारंटी नहीं है , अकेले में जाने दें /bin

यह वास्तव में बहुत ज्यादा है, इससे भी बदतर है। यदि आपको सभी यूनिक्स प्रणालियों के लिए अनुकूलता की आवश्यकता है , जिसमें सोलारिस और एआईएक्स जैसी चीजें शामिल हैं, जो उनके शेल वातावरण को परिगलित कर देती हैं 1995 तक। इसका मतलब है कि आपको पुराने जमाने के sort +Nसिंटैक्स जैसी चीजों का उपयोग करना होगा - जो कि नए सिस्टम गिरा दिए गए हैं! और इसका मतलब यह भी है कि कोई शेल फ़ंक्शन नहीं, कोई सरणियां, नहीं [[ ... ]], नहीं ${foo#glob}, $(( ... ))अंकगणित के लिए नहीं , संभवतः कोई $( ... )-स्टाइल कमांड प्रतिस्थापन नहीं है, बड़ा इनपुट कैसे प्राप्त कर सकता है, इस पर छोटे और अनिर्दिष्ट ऊपरी सीमा ...

आप शायद उस अनुकूलता से परेशान न हों , लेकिन अगर यह पहली बार में भी कोई समस्या है, तो मैं दृढ़ता से आपको एक ऐसी भाषा पर विचार करने की सलाह देता हूं, जो शेल की तुलना में कम भयानक है। मूल पर्ल दुभाषिया बैश की तुलना में उपलब्ध होने की अधिक संभावना है।


धन्यवाद। जैसा कि मूल रूप से कहा गया है "मेरे मामले में एकमात्र ओएस 'मुझे परवाह है कि उबंटू (डेबियन) और ओएसएक्स हैं।" ये केवल 5 सिस्टम हैं जो मैंने पिछले 5 वर्षों में उपयोग किए हैं (और मैं इनका बहुत उपयोग करता हूं), इसलिए यह है कि 'मैं' एक शेल स्क्रिप्ट लिख रहा हूं जो केवल उन पर काम करेगा। मुझे एक सार्वभौमिक लिपि और उसके द्वारा प्रस्तुत की जाने वाली सीमाओं की कोई आवश्यकता नहीं है।
माइकल डुरंट

@MichaelDurrant उस मामले में, आपको शेल स्क्रिप्ट लिखने की आवश्यकता नहीं है, और नहीं भी करना चाहिए। इसके बजाय आपको बेहतर स्क्रिप्टिंग भाषाओं में से किसी का भी उपयोग करना चाहिए जो एक विकल्प है जब आपको कुल पोर्टेबिलिटी की आवश्यकता नहीं होती है।
zwol
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.