"/ बिन / श" अंक "/ बिन / बाश" करने पर शेल स्क्रिप्ट चलाना


11

मैंने इस प्रश्न में निम्नलिखित पढ़ा है :

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

उपरोक्त उद्धरण मानता है कि /bin/shएक लिंक है जो इंगित करता है /bin/bash

लेकिन मुझे समझ में नहीं आ रहा है कि "sh के रूप में आह्वान" का क्या मतलब है ।


कहो कि मेरे पास निम्नलिखित स्क्रिप्ट है जिसे "script.sh" कहा जाता है:

#!/bin/bash
echo "Hello World"

कृपया मुझे निम्नलिखित में से प्रत्येक मामले में बताएं कि क्या स्क्रिप्ट सामान्य bashमोड में चलेगी या POSIX मोड में (मान लें कि मैंने चल रहे टर्मिनल में निम्न कमांड निष्पादित की है bash):

  1. sh script.sh
  2. bash script.sh
  3. ./script.sh

अब कहते हैं कि मेरे पास निम्नलिखित स्क्रिप्ट है जिसे "script.sh" कहा जाता है (जो उपरोक्त स्क्रिप्ट की तरह है लेकिन शेबंग के बिना):

echo "Hello World"

कृपया मुझे निम्नलिखित में से प्रत्येक मामले में बताएं कि क्या स्क्रिप्ट सामान्य bashमोड में चलेगी या POSIX मोड में (मान लें कि मैंने चल रहे टर्मिनल में निम्न कमांड निष्पादित की है bash):

  1. sh script2.sh
  2. bash script2.sh
  3. ./script2.sh

जवाबों:


19

केवल केस 1 और 4 POSIX मोड में चलेगा (यह मानते हुए कि shबैश है और श के कुछ अन्य कार्यान्वयन नहीं है)। कोई भी मामला जो स्पष्ट रूप से bashबिना कॉल करता है --posix, चाहे वह शेबंग से हो या नहीं। कोई भी मामला जो स्पष्ट रूप से कहता है sh। शेबंग का उपयोग केवल तब किया जाता है जब कोई शेल पहले से ही स्क्रिप्ट के लिए स्पष्ट रूप से शुरू नहीं हुआ था।

केस 6, यदि आपका टर्मिनल चल रहा है bash, तो POSIX मोड में नहीं चलेगा और बैश इसे अपने आप इस्तेमाल करेगा। अपने टर्मिनल zsh बजाय चल रहे थे, तो मामला 6 होगा भी POSIX मोड में चलाते हैं। POSIX वास्तव में उस मामले में क्या होना चाहिए, इसके बारे में अस्पष्ट है , और बैश और zsh ने वहां अलग-अलग विकल्प बनाए। बैश स्क्रिप्ट का उपयोग करके खुद को आमंत्रित करता है, जबकि zsh उपयोग करता है sh(जो कुछ भी होता है)। अन्य गोले भी उस बिंदु पर भिन्न होते हैं।


अपनी स्क्रिप्ट बॉडी बनाने के लिए एक सरल तरीका है कि आप किस मोड में हैं:

kill -SIGHUP

जो POSIX मोड में एक त्रुटि के साथ विफल हो जाएगा , लेकिन killइसके बाहर के उपयोग के निर्देश दें। यह एक आसान अंतर है और यह बैश संस्करणों की एक लंबी श्रृंखला के माध्यम से काम करता है जहाँ तक आपका सामना होने की संभावना है।


3
ऐसी अन्य चीजें हैं जो पर्यावरण चर की bashतरह POSIX मोड में चलने के लिए बाध्य होंगी POSIXLY_CORRECTया SHELLOPTS=posix
स्टीफन चेजलस

1
[ -o posix ]यह जांचने के लिए एक अधिक स्पष्ट तरीका है कि आप बैश में पॉज़िक्स मोड में चल रहे हैं (अन्य शेल में नहीं (यश को छोड़कर), इसलिए आप ऐसा shस्क्रिप्ट में नहीं करना चाहेंगे )। POSIXLY_CORRECT=1 bash -c '[ -o posix ] && echo yes'आउटपुट yes`
स्टीफन चेज़लस

2
6 के मामले में, bash स्क्रिप्ट को POSIX मोड में स्वयं के साथ इनवॉइस करता है जब वह POSIX मोड में होता है क्योंकि POSIX की आवश्यकता होती है। POSIX में वह-बैंग तंत्र निर्दिष्ट नहीं करता है, और निष्पादन योग्य स्क्रिप्ट के लिए 6 एकमात्र POSIX तरीका है और यह स्पष्ट रूप से निर्दिष्ट है (POSIX वातावरण में, स्क्रिप्ट का अर्थ एक कंप्लेंट श उपयोगिता द्वारा समझा जाता है)।
स्टीफन चेजलस

8

"के रूप में लागू" संदर्भित करता है जो कुछ भी यह है कि इस प्रक्रिया को अपने "zeroth" कमांड लाइन तर्क में बैश डालता है शुरू, argv[0]

जब किसी प्रोग्राम को exec*()syscalls के साथ शुरू किया जाता है , तो उन्हें वास्तव में प्रोग्राम से संबंधित बाइनरी फ़ाइल का नाम पता नहीं चलता है, लेकिन इसके बजाय कॉलिंग प्रक्रिया जो कुछ भी वहां है उसे डालने के लिए स्वतंत्र है। आमतौर पर, नाम, फाइलसिस्टम से लिया जाता है, इसलिए यदि आप दौड़ते हैं /bin/sh, तो यही है। और अगर /bin/shबैश है, तो उसे सिम्लिंक होना जरूरी नहीं है, यह एक हार्ड लिंक या शेल प्रोग्राम की सिर्फ एक कॉपी हो सकती है।

"प्रोग्राम का नाम" सेट करने के एक उदाहरण के रूप में, बैश की execकमांड -aविकल्प के साथ शून्य तर्क सेट कर सकती है। (हम पर्ल के साथ भी कर सकते हैं, या सीधे सी के साथ, आदि)

यहाँ, mynameएक सरल सी प्रोग्राम है जो सिर्फ अपने शून्य तर्क को प्रिंट करता है, नाम वह स्वयं देखता है:

$ ./myname 
I am ./myname
$ (exec -a something ./myname )
I am something
$ mv ./myname somename
$ ln -s somename othername
$ ./somename 
I am ./somename
$ ./othername
I am ./othername

स्रोत:

#include <stdio.h>
int main(int argc, char *argv[]) {
    printf("I am %s\n", argv[0]);
    return 0;
}

लेकिन, गिने-चुने सवालों के जवाब देने के लिए ...

(1 & 4) दौड़ने sh somescriptसे shआपके जो कुछ भी है PATH, वह चलेगा , /bin/shलेकिन संभवतः ऐसा ही कुछ/usr/xpg4/bin/sh

  • यदि यह बैश है, तो यह POSIX मोड में चलता है, क्योंकि यह नाम देखता है sh
  • यदि यह Z शेल या कॉर्न शेल है, तो यह नाम देखता है sh, लेकिन यह "SH संगत" मोड में चलता है, जिसका उद्देश्य बॉर्न शेल संगत होना है और उन दोनों शेल में पूर्ण POSIX अनुरूप मोड के लिए अलग-अलग है। ।
  • यह निश्चित रूप से अल्मक्विस्ट शेल, एक वास्तविक बॉर्न शेल या कुछ और हो सकता है।

(2 और 5) रनिंग bash somescriptनियमित बैश मोड में चलेगी (फिर से, यह निश्चित रूप से इस बात पर निर्भर करता है कि bashआपके पास क्या PATHहै।)

(३) यहाँ, प्रोग्राम फ़ाइल के स्थान पर सीधे सिस्टम कॉल को स्क्रिप्ट का नाम दिया गया है। कर्नेल हैशबैंग लाइन पढ़ता है और स्क्रिप्ट चलाने के लिए इसका उपयोग करता है।

(६) यह जटिल है। यह (3) के समान है, लेकिन प्रोग्राम शुरू करने के लिए सिस्टम कॉल विफल रहता है ( ENOEXEC (Exec format error)), क्योंकि कोई हैशबैंग लाइन नहीं है। आगे क्या होता है यह इस बात पर निर्भर करता है कि आप जो शेल चला रहे हैं वह पॉसिक्स मोड में ही है। POSIX के लिए आवश्यक है कि POSIX-conformant शेल एक विशिष्ट अंदाज में प्रतिक्रिया के साथ व्यवहार करे ENOEXEC हालांकि, "कुछ कमांड एक शेल के पास होने के बराबर है", जिसका मतलब है कि अलग-अलग गोले अलग-अलग काम करते हैं।

  • बॉर्न अगेन शेल अपने पहले कमांड-लाइन तर्क के रूप में स्क्रिप्ट के नाम के साथ उसी मोड में फिर से चलाता है । अपने POSIX- अनुरूप मोड में, यह निश्चित रूप से अपने POSIX- अनुरूप मोड में चल रहा है, इस प्रकार POSIX- अनुरूप शेल को लागू करने के लिए POSIX आवश्यकता का पालन करता है।
  • Z शेल, अल्मक्विस्ट शेल, और कॉर्न शेल /bin/shस्क्रिप्ट के नाम के साथ अन्य तर्कों से पहले अपने पहले कमांड-लाइन तर्क के रूप में चलते हैं। Z शेल, अल्मक्विस्ट शेल, और कॉर्न शेल (POSIX-conformant shell) को लागू करने का प्रयास करने के लिए कहते हैं कि /bin/shकार्यक्रम एक है।

क्या आप कृपया इस C प्रोग्राम का स्रोत कोड साझा कर सकते हैं ..
GypsyCosmonaut

int main(int argc, char *argv[]){printf("I am %s\n",argv[0]);}
स्टिग हेमर

तो इतना ही है।
ilkachachu

4

निष्पादित शेल या तो कमांड लाइन में कहा जाता है या शेबंग में एक है (यदि कमांड लाइन इसे निर्दिष्ट नहीं करता है)।

तो, संस्करण 1 और 4 के साथ चला जाएगा sh, 2 और 5 को बैश और 6 के साथ नहीं चलेगा यदि आप श (और कुछ अन्य) का उपयोग कर रहे हैं। बैश स्क्रिप्ट शुरू करता है। Ksh भी। Zsh इसे श के रूप में शुरू करता है।

shबैश से जुड़े होने पर केवल वही लोग शुरू होंगे जो पॉज़िक्स विकल्प का उपयोग करेंगे /bin/sh

यह जानने के लिए कि क्या कोई बैश ksh या zsh वर्जन इसे चला रहा है, इस रेखा को अपनी स्क्रिप्ट में जोड़ें:

echo "Hello World $BASH_VERSION $KSH_VERSION $ZSH_VERSION"
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.