क्या इसकी शबंग रेखा के अनुसार स्क्रिप्ट चलाने की आज्ञा है?


46

अगर मैं एक bash स्क्रिप्ट निष्पादित करना चाहता हूं, जिसमें इसका निष्पादन अनुमति सेट नहीं है, तो मैं कर सकता हूं:

bash script.sh

bashयदि स्क्रिप्ट निष्पादन योग्य नहीं है और मुझे सही दुभाषिया नहीं पता है तो मुझे इसका क्या उपयोग करना चाहिए ? क्या एक कमांड है जो शेबंग लाइन से दुभाषिया को देखता है और इसके साथ स्क्रिप्ट निष्पादित करता है?


क्या गलत है बैश?
स्टेफेन

@ जल्दबाज़ी करें कि आप कैसे जानते हैं कि प्रश्न में फाइल एक बैश स्क्रिप्ट है?
मुरु

@ मुरू प्रश्न से बोली: "अगर मैं एक बैश स्क्रिप्ट को निष्पादित करना चाहती हूं ..." इसके अलावा (भले ही यह बैश स्क्रिप्ट नहीं है), यदि bash whateverकाम करता है, तो कुछ अलग क्यों उपयोग करें? बैश लगभग हर * ix सिस्टम पर उपलब्ध है, इसलिए परेशान क्यों ...
Stepffen

1
@ क्या आपने बाकी प्रश्न पढ़े हैं? वे कहते हैं: "अगर ... तो मैं कर सकता हूं: ..." और "मुझे बैश के बजाय क्या उपयोग करना चाहिए अगर ... मुझे सही दुभाषिया नहीं पता है ?"
मुरु

@ मुरू: शायद मुझे स्पष्ट नहीं दिख रहा है। लेकिन यदि प्रश्न में कहा गया है, तो फ़ाइल / है / एक शबंग रेखा, बैश ठीक वही करेगी जो उससे मांगी जाती है। जैसा कि नीचे दिए गए उत्तर के अनुसार होगा। तो बैश का उपयोग नहीं करने का क्या फायदा है?
स्टेफेन

जवाबों:


67

हां। इसे कहा जाता है perl:

perl foo.bash    # works
perl foo.lua     # works
perl foo.clisp   # works
perl foo.csh     # works
perl foo.php     # works
perl foo.gnuplot # works (no arguments)
perl foo.pl      # works (obviously)
perl foo.py      # works
perl foo.sh      # works
perl foo.tcl     # works
perl foo.rb      # works
perl foo.nodejs  # works
perl foo.r       # works
perl foo.oct     # works
perl foo.csharp  # works (no arguments)

यह पर्ल के दस्तावेज में उल्लिखित है :

यदि #!रेखा में "पर्ल" शब्द नहीं है और न ही शब्द "इंडिर" है, #!तो पर्ल इंटरप्रेटर के बजाय प्रोग्राम को नाम दिया गया है। यह थोड़ा विचित्र है, लेकिन यह उन मशीनों पर लोगों की मदद करता है जो ऐसा नहीं करते हैं #!, क्योंकि वे एक कार्यक्रम बता सकते हैं कि उनका SHELL / usr / bin / perl है, और पर्ल तब उनके लिए सही दुभाषिया के लिए कार्यक्रम भेजेंगे।


40
खैर, यह सिर्फ गंदा है।
स्लिम

1
फ़ाइल एक्सटेंशन .jsभी काम करता है?
पिसिस

1
इसके अलावा, क्या मशीनों नहीं करते हैं #!। मुझे अब कुछ और लग रहा है, और इस समस्या का अनुभव नहीं किया है।
पिसिस

1
ठीक है, यह सिर्फ आपका उदाहरण है कि फाइल से कई शेलंग लाइनों को प्रदर्शित करने के बजाय बहुत सारे फ़ाइल एक्सटेंशनों को उजागर किया गया था , और मुझे लगता है कि मैंने अनुमान लगाया कि इसकी भविष्यवाणी कैसे काम करती है।
3

2
मुझे यह पसंद है कि man perlrunभेड़चाल में कैसे स्वीकार किया जाता है कि यह "थोड़ा विचित्र" है :)। मुझे लगता है कि इसे गैर- UNIX वातावरण और UNIX के बहुत पुराने संस्करणों के उद्देश्य से एक जिज्ञासा के रूप में माना जाना चाहिए ।
स्लिम

25

लिपियों में जरूरी नहीं कि एक शेबंग हो

स्क्रिप्ट दुभाषिया से चला गया था, तो आप यकीन है कि यह मामला है नहीं हो सकता सब परस्क्रिप्ट, दुभाषिया से चलाने कुटिया की जरूरत नहीं है , यदि आप कोड को चलाने के लिए दुभाषिया कहते हैं।

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

संक्षेप में नियम:

  1. जब आप स्क्रिप्ट चलाते हैं, तो दुभाषिया को कॉल करना हमेशा संभव है कि शेबांग, निष्पादन योग्य या नहीं, शेबंग या नहीं को ओवररेल करता है।
  2. यदि निष्पादन योग्य नहीं है और दुभाषिया से नहीं चलते हैं , तो स्क्रिप्ट को कोई शेबंग की आवश्यकता नहीं है।
  3. यदि स्क्रिप्ट पहले दुभाषिया को बुलाए बिना चलाया जाता है, तो उसे यह जानने की आवश्यकता है (और उपयोग करता है) कि क्या दुभाषिया को कॉल करने के लिए पता लगाने के लिए, और इसके शेपबिटर से दुभाषिया को बुलाने के लिए "अनुमति" लेने के लिए निष्पादन योग्य होना चाहिए।

यदि स्क्रिप्ट में कोई भी शेबंग नहीं है, लेकिन स्क्रिप्ट के अंदर कोई (प्रत्यक्ष *) जानकारी नहीं है जो यह बताए कि किस दुभाषिया का उपयोग करना है।

यह कहने के बाद

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

एक उदाहरण

#!/usr/bin/env python3
import subprocess
import sys

args = sys.argv[1:]; script = args[0]

try:
    lang = open(script).readlines()[0].replace("#!", "").strip().split()[-1]
    cmd = [lang, script]+args[1:]
    subprocess.call(cmd)
except (PermissionError, FileNotFoundError, IndexError):
    print("No valid shebang found")
  • इसे इस रूप tryrunमें सहेजें $PATH(उदाहरण के लिए ~/bin, यदि यह मौजूद नहीं है तो निर्देशिका बनाएं, लॉग आउट करें और वापस जाएं), इसे निष्पादित करें । फिर चल रहा है:

    tryrun /path/to/nonexecutablescript

    कॉल (परीक्षण) मेरे गैर-निष्पादन योग्य pythonऔर bashस्क्रिप्ट पर सही दुभाषिया ।

व्याख्या

  • स्क्रिप्ट बस स्क्रिप्ट की पहली पंक्ति को पढ़ती है, #!दुभाषिया को हटाने के लिए शेष का उपयोग करती है।
  • यदि यह एक वैध दुभाषिया को कॉल करने में विफल रहता है, तो यह PermissionErrorया तो एक को बढ़ा देगा FileNotFoundError

ध्यान दें

विस्तार ( .sh, .pyआदि) लिनक्स पर उचित दुभाषिया का निर्धारण करने में कोई भूमिका नहीं जो भी निभाता है।


(*) कोड से वाक्य रचना निर्धारित करने के लिए "स्मार्ट" अनुमान-एल्गोरिदम विकसित करना निश्चित रूप से संभव है।)


ठीक है, तो इसका मतलब है कि हालांकि लिनक्स में कहीं भी शेबंग निष्कर्षण लागू किया गया है (ताकि यह निष्पादन योग्य सरप्लस के लिए सही दुभाषिया का चयन कर सके), यह एक स्टैंडअलोन मानक कमांड के रूप में प्रदान नहीं किया गया है।
ऐवर

@ शिवर ने इस मुद्दे को नहीं उठाया, लेकिन इसके बिना कोड चलाना पूरी तरह से संभव है।
जैकब व्लिजम

@ ऐवर आह, मैं देख रहा हूं कि आपका क्या मतलब है। यदि स्क्रिप्ट निष्पादन योग्य है और कमांड में भाषा के बिना चलती है, तो स्क्रिप्ट दुभाषिया को बुलाती है, अन्य तरीके से नहीं।
याकूब Vlijm

1
@JacobVlijm मैं यह नहीं कहूंगा कि "स्क्रिप्ट दुभाषिया को बुलाती है", अधिक "जैसे लिनक्स कर्नेल स्क्रिप्ट को निष्पादित करते समय कॉल करने के लिए दुभाषिया को निकालने के लिए शबंग लाइन लेता है"।
पाओलो एबरमन

@ Pa @loEbermann धन्यवाद! बिल्कुल सच है। कर्नेल पूरी तरह से या तो तरीके से देखभाल करता है, लेकिन लाक्षणिक रूप से, और मैं समझने के लिए बेहतर समझता हूं, यह कहना है कि स्क्रिप्ट को कॉल करने वाले (और वास्तव में ऐसा करने के लिए) की देखभाल करने के लिए "अनुमति" है। शब्दांकन के बारे में निश्चित नहीं है, लेकिन मैं इसका वर्णन करना चाहता हूं जैसे कि स्क्रिप्ट पर पहल होती है, जबकि कर्नेल वास्तव में काम करता है।
२०

6

आप इसे इस तरह से स्क्रिप्ट के साथ प्राप्त कर सकते हैं:

#!/bin/bash

copy=/tmp/runner.$$
cp $1 ${copy}
chmod u+x ${copy}
${copy}
rm ${copy}

इस प्रकार:

$ echo "echo hello" > myscript
$ ./myscript
bash: ./myscript: Permission denied
$ ./runscript myscript 
hello

मैं ऐसा करने के खिलाफ सलाह देता हूं। कारण एक कारण हैं। यह सबमिशन परमिशन के लिए एक प्रोग्राम है।

ध्यान दें कि हेबैंग हैंडलिंग एक कर्नेल फ़ंक्शन (लिनक्स स्रोत कोड - fs/binfmt_script.c) में है। मौलिक रूप से एक स्क्रिप्ट को सीधे आमंत्रित करने वाली प्रक्रिया के बारे में नहीं पता है #!- कर्नेल इसका उपयोग वर्कआउट करने के लिए करता है कि उसे एक दुभाषिया लॉन्च करने की आवश्यकता है।


2
मैंने हमेशा यह मान लिया था कि यह शेल का कार्य है, कर्नेल का नहीं। आज कुछ नया सीखा।
नावक

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