सवाल मुझे #! / Bin / bash का उपयोग कब करना चाहिए और जब #! / Bin / sh?


कब है #!/bin/bash से अधिक उपयुक्त #!/bin/sh एक शेल स्क्रिप्ट में?


97
2017-10-10 07:02


मूल


जब आप उपयोग कर रहे हैं bash के बजाय कार्यों और वाक्यविन्यास sh कार्य और वाक्यविन्यास। - Mokubai♦
देख stackoverflow.com/questions/5725296/... - SPRBRN
अगर यह किसी की मदद करता है, तो मैंने देखा है vim हाइलाइट करेगा bashअगर आपकी लिपि में है तो #!/bin/sh मामला। मैं केवल इसे बदलता हूं bash अगर चीजें बाश-फीचर्स की आवश्यकता शुरू करने के लिए पर्याप्त बालों वाली हो जाती हैं। - SeldomNeedy
@SeldomNeedy हालांकि कुछ चीजें डिफ़ॉल्ट रूप से किसी भी पॉज़िक्स शैल में ठीक काम करती हैं। $(...) विशेष रूप से अप्रिय है। इसके अलावा, उनमें से कुछ सूक्ष्म हैं [<(...) तथा cmd >& file उदाहरण के लिए, किसी भी त्रुटि को हाइलाइट करने में कोई त्रुटि न पाएं, उनके पास उनके साथ या उसके बिना, उनके लिए विशेष हाइलाइटिंग नहीं है g:is_bash] - Random832
@ Random832 ऐसा लगता है कि हाल ही में इस विषय पर कुछ गतिविधि हुई है विम का मुद्दा-ट्रैकर। - SeldomNeedy


जवाब:


संक्षेप में:

  • ऐसे कई गोले हैं जो सुपरसैट को कार्यान्वित करते हैं POSIX sh विनिर्देश। विभिन्न प्रणालियों पर, /bin/sh राख, बैश, डैश, क्ष, zsh, और सी के लिए एक लिंक हो सकता है। (यह हमेशा शर्मिंदा होगा हालांकि - सीएसएच या मछली कभी नहीं।)

  • जब तक आप चिपके रहते हैं sh केवल विशेषताएं, आप (और शायद यहां तक ​​कि भी) उपयोग कर सकते हैं #!/bin/sh और लिपि को ठीक काम करना चाहिए, इससे कोई फर्क नहीं पड़ता कि यह कौन सा खोल है।

  • यदि आप बैश-विशिष्ट विशेषताओं (उदा। सरणी) का उपयोग शुरू करते हैं, तो आपको विशेष रूप से बैश का अनुरोध करना चाहिए - क्योंकि, यदि भी हो /bin/sh पहले ही बैश पर आक्रमण करता है तुंहारे प्रणाली, यह नहीं हो सकता है हर कोई है सिस्टम, और आपकी स्क्रिप्ट वहां नहीं चलेगी। (वही पाठ्यक्रम zsh और ksh पर लागू होता है।) आप इसका उपयोग कर सकते हैं shellcheck bashisms की पहचान करने के लिए।

  • भले ही स्क्रिप्ट केवल व्यक्तिगत उपयोग के लिए है, आप शायद ध्यान दें कि कुछ ओएस बदलते हैं /bin/sh उन्नयन के दौरान - उदा। डेबियन पर यह बैश होता था, लेकिन बाद में बहुत कम डैश के साथ बदल दिया गया था। स्क्रिप्ट्स जो बाशिसम का इस्तेमाल करती थीं लेकिन थीं #!/bin/sh अचानक टूट गया।

हालाँकि:

  • यहाँ तक की #!/bin/bash बहुत सही नहीं है। विभिन्न प्रणालियों पर, बैश में रह सकता है /usr/bin या /usr/pkg/bin या /usr/local/bin

  • एक और विश्वसनीय विकल्प है #!/usr/bin/env bash, जो $ पाथ का उपयोग करता है। (हालांकि env उपकरण स्वयं सख्ती से गारंटी नहीं है, /usr/bin/env अभी भी अधिक सिस्टम पर काम करता है /bin/bash कर देता है।)


143
2017-10-10 14:03



अच्छा उत्तर। क्या आप इसे सीडब्ल्यू बनाना चाहते थे? - Mokubai♦
बैश चलाए जाने पर बस एक टिप्पणी /bin/sh तो यह नकल करने की कोशिश करेगा sh विशेषताएं (देखें मैन पेज), सुनिश्चित नहीं है कि इस मोड में बैश विशिष्ट सुविधाएं उपलब्ध हैं। env उपकरण एक पॉज़िक्स उपकरण है यह अधिकांश वितरण में पाया जाना चाहिए, लेकिन मुझे यकीन है कि कुछ लोग पॉज़िक्स का सम्मान नहीं कर सकते हैं। - Brice
नहीं, वास्तव में POSIX विशेष रूप से राज्यों इसमें शामिल नहीं माना जा सकता है /bin: "अनुप्रयोगों को ध्यान रखना चाहिए कि खोल के लिए मानक पथ को या तो / bin / sh या / usr / bin / sh माना जा सकता है, और getconf पाथ द्वारा लौटाए गए पीएटीएच की पूछताछ द्वारा निर्धारित किया जाना चाहिए, यह सुनिश्चित करना कि लौटा पथनाम एक पूर्ण है पथनाम और अंतर्निहित शेल नहीं"। और देखें यह प्रश्न और, विशेष रूप से यह जवाब। - terdon
हम्म, ठीक है, इसका मतलब है कि POSIX वास्तव में होने के लिए एक पोर्टेबल तरीका परिभाषित नहीं करता है #! स्क्रिप्ट काम करते हैं? - grawity
पॉज़िक्स शा है नहीं बोर्न: यह बोर्न के प्रत्यक्ष वंशज की तुलना में प्रारंभिक क्षीण का व्युत्पन्न है। उन्हें अलग करना आसान है: echo foo ^ cat का उत्सर्जन करता है foo ^ cat POSIX sh में, और केवल उत्सर्जित करता है foo बोर्न में (जैसा ^ वहां एक पाइप चरित्र है)। - Charles Duffy


उस शैल से संबंधित शेबैंग का उपयोग करें जिसका उपयोग आप वास्तव में अपनी स्क्रिप्ट को विकसित और डीबग करने के लिए करते थे। अर्थात। अगर आपका लॉगिन खोल है bash, और आप अपनी स्क्रिप्ट को अपने टर्मिनल में निष्पादन योग्य के रूप में चलाते हैं, उपयोग करें #!/bin/bash। केवल यह न मानें कि चूंकि आपने सरणी (या जो भी नहीं) का उपयोग नहीं किया है bash सुविधा जो आप जानते हैं), आप जो भी खोल पसंद करते हैं उसे चुनने के लिए सुरक्षित हैं। गोले के बीच कई सूक्ष्म अंतर हैं (echo, फ़ंक्शन, लूप, आप इसे नाम दें) जिन्हें उचित परीक्षण के बिना खोजा नहीं जा सकता है।

इस पर विचार करें: यदि आप छोड़ते हैं #!/bin/bash और आपके उपयोगकर्ताओं के पास यह नहीं है, वे एक स्पष्ट त्रुटि संदेश देखेंगे, जैसे कुछ

Error: /bin/bash not found

अधिकांश उपयोगकर्ता उचित पैकेज स्थापित करके इसे एक मिनट के नीचे ठीक कर सकते हैं। दूसरी तरफ, यदि आप शेबांग को प्रतिस्थापित करते हैं #!/bin/sh और इसे एक प्रणाली पर परीक्षण करें जहां /bin/sh एक सिम्लिंक है /bin/bash, आपके उपयोगकर्ता जो नहीं है bash परेशानी में होगा। वे सबसे अधिक संभावना एक गुप्त त्रुटि संदेश देखेंगे जैसे:

Error in script.sh line 123: error parsing token xyz

इसमें कुछ घंटे लग सकते हैं, और इस बारे में कोई संकेत नहीं होगा कि उन्हें किस खोल का उपयोग करना चाहिए था।

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


18
2017-10-14 13:55



@ हास्टुर मुझे आपकी टिप्पणी नहीं मिली है। शेबांग निश्चित रूप से परिभाषित करेगा कि स्क्रिप्ट को चलाने के लिए किस शेल का उपयोग किया जाएगा, क्या आपको लगता है कि मेरा जवाब अन्यथा मायने रखता है? - Dmitry Grigoryev
रहने भी दो। मैंने भाग को गलत समझा "आप क्यों उपयोग करना चाहते हैं"... - Hastur


आपको केवल कभी भी उपयोग करना चाहिए #! /bin/sh

आपको कभी भी शेल स्क्रिप्ट में बैश (या zsh, या fish, या ...) एक्सटेंशन का उपयोग नहीं करना चाहिए।

आपको केवल शैल स्क्रिप्ट लिखना चाहिए जो काम करते हैं कोई भी शैल भाषा का कार्यान्वयन (सभी "उपयोगिता" कार्यक्रमों सहित जो शैल के साथ ही जाते हैं)। इन दिनों आप कर सकते हैं शायद लेना POSIX.1-2001 (नहीं -2008) शैल और उपयोगिताएं क्या करने में सक्षम हैं, इसके लिए आधिकारिक के रूप में, लेकिन इस बात से अवगत रहें कि आपको अपनी स्क्रिप्ट को विरासत प्रणाली (जैसे सोलारिस या एईक्स) में पोर्ट करने के लिए बुलाया जा सकता है जिसका शेल और उपयोगिताएं लगभग 1992 में जमे हुए थीं।

क्या, गंभीरता से ?!

हां गंभीरतापूर्वक।

यह बात है: शैल एक है भयानक प्रोग्रामिंग भाषा। इसके लिए एकमात्र चीज यह है कि वह है /bin/sh एकमात्र स्क्रिप्ट दुभाषिया है कि हर एक यूनिक्स स्थापना की गारंटी है।

यहां दूसरी बात है: मूल पर्ल 5 दुभाषिया के कुछ पुनरावृत्ति (/usr/bin/perl) है अधिक एक यादृच्छिक रूप से चयनित यूनिक्स स्थापना से उपलब्ध होने की संभावना है (/(usr|opt)(/(local|sfw|pkg)?)?/bin/bash है। अन्य अच्छी पटकथा भाषाएं (पायथन, रूबी, नोड.जेएस, इत्यादि - शैल की तुलना करते समय मैं उस श्रेणी में PHP और Tcl भी शामिल करूंगा) लगभग बाश और अन्य विस्तारित गोले के रूप में भी उपलब्ध हैं।

इसलिए, यदि आपके पास बैश स्क्रिप्ट लिखने का विकल्प है, आपके पास एक प्रोग्रामिंग भाषा का उपयोग करने का विकल्प है जो इसके बजाय भयानक नहीं है।

अभी व, सरल शैल स्क्रिप्ट्स, जिस तरह से क्रॉन जॉब या कुछ से अनुक्रम में कुछ प्रोग्राम चलाते हैं, उन्हें खोल स्क्रिप्ट के रूप में छोड़ने में कुछ भी गलत नहीं है। लेकिन सरल शैल स्क्रिप्ट को सरणी या फ़ंक्शंस की आवश्यकता नहीं होती है या [[ यहाँ तक की। और आपको केवल लिखना चाहिए उलझा हुआ शैल स्क्रिप्ट्स जब आपके पास कोई अन्य विकल्प नहीं है। उदाहरण के लिए, Autoconf स्क्रिप्ट, ठीक से अभी भी खोल स्क्रिप्ट हैं। लेकिन उन स्क्रिप्ट को चलाना है हर एक अवतार /bin/sh यह प्रोग्राम कॉन्फ़िगर किया जा रहा है के लिए प्रासंगिक है। और इसका मतलब है कि वे किसी भी एक्सटेंशन का उपयोग नहीं कर सकते हैं। आपको शायद इन दिनों पुरानी मालिकाना यूनिक्स की परवाह नहीं है, लेकिन शायद आप चाहिए वर्तमान ओपन-सोर्स बीएसडी के बारे में परवाह है, जिनमें से कुछ स्थापित नहीं हैं bash डिफ़ॉल्ट रूप से, और एम्बेडेड वातावरण जो आपको केवल एक न्यूनतम खोल देते हैं और busybox

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


5
2017-10-11 06:30



क्षमा करें लेकिन यह थोड़ा मूर्ख है। हां, अगर आप कुछ लिख रहे हैं जो मैं वितरित करूंगा और ii) विभिन्न वातावरणों के लिए, आपको मूलभूत रहना चाहिए sh। हालांकि, यह कहने से बहुत रोना है कि आपको करना चाहिए कभी नहीँ अन्य गोले का प्रयोग करें। हर दिन हजारों (शायद कई और) स्क्रिप्ट लिखी जाती हैं और उनमें से अधिकांश बहुमत केवल एक ही मशीन पर चलेंगे। आपकी सलाह उत्पादन कोड पर समझ में आता है, लेकिन दैनिक "sysdaminy" नौकरियों के लिए नहीं, जो कि अधिकांश स्क्रिप्ट के लिए लिखी जाती हैं। अगर मुझे पता है कि मेरी स्क्रिप्ट का उपयोग कभी भी मेरे द्वारा और लिनक्स मशीन पर किया जाएगा, तो बैश ठीक है। - terdon
@terdon मुद्दा यह है कि यदि आपके पास एक बैश स्क्रिप्ट लिखने का विकल्प है, तो आपके पास एक perl (या जो कुछ भी) स्क्रिप्ट लिखने का विकल्प भी है, और यह है हमेशा बेहतर विकल्प। - zwol
@terdon उत्तर निश्चित रूप से मूर्ख नहीं है, इसके बजाय आपकी टिप्पणी बस बेवकूफी है। शैल स्क्रिप्ट्स पर्ल की तुलना में डीबग करने के लिए भयानक हैं और ऐसे में, जिसके लिए कोई आसानी से ग्राफिकल डिबगिंग और सभी के साथ पूर्ण आईडीई का उपयोग कर सकता है। इसके अतिरिक्त, कुछ छोटी चीजों के लिए हर दिन लिखी गई स्क्रिप्ट्स को बदलना और फिर से बदलना पड़ता है, बढ़ते हैं, सहकर्मियों या नेट इत्यादि के उदाहरण के रूप में प्रतिलिपि बनाई जाती हैं। ऐसे जोखिम लेने का कोई कारण नहीं है। - Thorsten Schöning
@ ThorstenSchöning मैंने कहा थोड़ा सा मूर्ख। अगर यह थे यूनिक्स और लिनक्स या और भी स्टैक ओवरफ़्लो मैं भी सहमत हो सकता हूं। यदि हम सामान्य सर्वोत्तम अभ्यास, या पेशेवर प्रोग्रामर के बारे में बात कर रहे हैं, तो निश्चित रूप से मूल POSIX sh से चिपकना सबसे अच्छा है। हालांकि, यह है सुपर उपयोगकर्ता, अंतिम उपयोगकर्ताओं के उद्देश्य से एक साइट और लोगों को शेल स्क्रिप्ट लिखते समय कभी भी बैश या जेएसएच का उपयोग नहीं करना है, मेरी राय में, चरम है। - terdon
@terdon यह वास्तव में है अधिक महत्वपूर्ण, मेरी राय में, अंतिम उपयोगकर्ताओं को जटिल शैल स्क्रिप्ट लिखने से हतोत्साहित करने के लिए। पेशेवरों के औसत पर उच्च कौशल स्तर होता है (इस प्रकार वे जटिल शैल स्क्रिप्टिंग के नुकसान से निपटने में सक्षम होने की अधिक संभावना रखते हैं), कुछ परिशुद्धता के साथ पता होना चाहिए कि उन्हें पर्यावरण को पोर्टेबल करने की आवश्यकता है, और उन्हें भुगतान नहीं किया जा रहा है निराशा में - zwol


आम तौर पर यदि कार्यक्षमता की तुलना में समय अधिक महत्वपूर्ण है तो आप तेज़ खोल का उपयोग करेंगे। sh को अक्सर डैश करने के लिए अलिया किया जाता है और रूट के क्रॉन कार्यों या बैच ऑपरेशंस के लिए उपयोग किया जाता है जहां हर (नैनो) दूसरी गणना करता है।


3
2017-10-11 20:36



फाइल सिस्टम से एक अतिरिक्त खोल दुभाषिया लोड करना इस तरह के लाभ को अस्वीकार कर सकता है, और कुछ भी जहां नैनोसेकंड (जो वास्तविक मशीन चक्र के रूप में परिमाण के समान क्रम में हैं) गणना सी और असेंबली भाषा प्रोग्रामर का डोमेन है। - rackandboneman
नैनोसेकंड केवल क्रॉन नौकरियों में अंतर डालते हैं यदि आपके पास अरबों हैं, और क्रॉन वैसे भी कई को संभालने में सक्षम नहीं होगा। - Dmitry Grigoryev
यहां तक ​​कि अगर मैकेंज़म थोड़ा अतिरंजित हो गया है, तो कोई भी इनकार नहीं कर रहा है कि अधिक प्रदर्शन करना बेहतर है! "नैनो" भाग पर लटकाओ मत। (नैनोसेकंड्स सी में भी गिनती नहीं करते हैं जब तक कि यह वास्तविक समय प्रणाली या ऐसे पर एक आंतरिक पाश नहीं है!) - jpaugh
@jpaugh जब तक आप एक (विरासत) प्रणाली के साथ काम नहीं कर रहे हैं जो मानता है कि कुछ संचालन कम से कम एक निश्चित अवधि लेते हैं। होता है! - JAB


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


2
2017-11-24 18:41





  • sh (ज्यादातर मामलों के लिए), विशेष रूप से आवश्यक होने पर बाश (या ksh, या जो कुछ भी)

सबसे सुरक्षित रास्ता जब हार्ड कोडित किया जाएगा, / usr / bin /shellOfChoice लेकिन एक नया सम्मेलन मैं हमेशा उपयोग करने की कोशिश कर रहा हूं - परिवर्तन के माध्यम से 'डिफ़ॉल्ट स्थान' के रूप में परिवर्तन बदल सकता है:

#! / usr / bin / env sh या
 #! / usr / bin / env bash
या उदाहरण के लिए, पर्ल स्क्रिप्ट्स
 #! / usr / bin / env perl -w

बेशक, जब आपके पास एक स्क्रिप्ट का कोई कारण नहीं है जो स्वचालित रूप से एक नया पाथ नहीं लेता है, तो इसे हार्ड-कोडित करना जारी रखें - और फिर / usr / bin / कुछ उपयोग करने का सबसे संभावित मार्ग होना चाहिए।


1