शबंग और रास्ता


22

एक चरवाहे को एक मार्ग की आवश्यकता क्यों है?

गलत

#!ruby

सही बात

#!/usr/local/bin/ruby

#!/usr/bin/env ruby

ऑपरेटिंग सिस्टम में एक पंजीकृत कमांड के लिए पथ के बारे में जानकारी होनी चाहिए, और यह अभी भी इसे दिए जाने की उम्मीद क्यों करता है?

जवाबों:


22

संभवतः कर्नेल को सरल रखने के लिए। मुझे नहीं लगता कि कर्नेल कभी निष्पादन योग्य खोजने के लिए आपका रास्ता खोजता है। वह सी लाइब्रेरी द्वारा नियंत्रित किया जाता है। #!प्रसंस्करण कर्नेल में किया जाता है, जो मानक सी लाइब्रेरी का उपयोग नहीं करता है।

इसके अलावा, मुझे नहीं लगता कि कर्नेल की धारणा है कि आपका रास्ता क्या है। $PATHएक पर्यावरण चर है, और केवल प्रक्रियाओं में एक वातावरण होता है। कर्नेल नहीं करता है। मुझे लगता है कि यह उस प्रक्रिया के वातावरण का उपयोग कर सकता है जिसने निष्पादन किया था, लेकिन मुझे नहीं लगता कि वर्तमान में कर्नेल में कभी भी पर्यावरण चर की तरह पहुंचता है।


5

आप PATHशब्दार्थ का उपयोग करके खोज कर सकते हैं env, इसलिए:

#!/usr/bin/env ruby  

आप जिस शब्दार्थ से चाहेंगे

#!ruby

कारण यह PATHहै कि अच्छा अभ्यास नहीं माना जाता है, यह है कि स्क्रिप्ट पैथ पर्यावरण चर की सामग्री के बारे में कोई धारणा नहीं बना सकती है, जहां बायनेरिज़ के "अनुक्रमिक निर्भरता मॉडल" को तोड़ दिया गया है

  1. /bin बूट समय पर आवश्यक निष्पादन योग्य शामिल हैं;
  2. /usr/bin ओएस इंस्टॉलेशन द्वारा उपयोग किए जाने वाले अन्य निष्पादन योग्य हैं;
  3. /usr/local/bin सिस्टम प्रशासक द्वारा स्थापित निष्पादक सम्‍मिलित करता है जो बेस OS का भाग नहीं है।
  4. ~/bin उपयोगकर्ता के स्वयं के निष्पादनयोग्य शामिल हैं।

प्रत्येक स्तर को अनुक्रम में बाद में बायनेरिज़ के अस्तित्व को नहीं मानना ​​चाहिए, जो अधिक "अनुप्रयोग" हैं, लेकिन पहले बायनेरिज़ पर भरोसा कर सकते हैं, जो अधिक "मौलिक" हैं। और PATH वैरिएबल एप्लीकेशन से मौलिक में चला जाता है, जो कि ऊपर की प्राकृतिक निर्भरता के विपरीत दिशा है।

समस्या का वर्णन करने के लिए, अपने आप से पूछें कि क्या होता है यदि एक स्क्रिप्ट उस स्क्रिप्ट में ~/binआक्रमण करती है जो /usr/local/binरूबी को आमंत्रित करती है? क्या उस स्क्रिप्ट को ओएस स्थापित संस्करण पर निर्भर करना चाहिए /usr/bin/ruby, या व्यक्तिगत प्रतिलिपि पर उपयोगकर्ता के पास क्या होना चाहिए ~/bin/ruby? PATHखोज पूर्व से संबंधित अप्रत्याशित शब्दार्थ देता है (शायद ~/bin/rubyएक टूटा हुआ प्रतीकात्मक लिंक है), जबकि #!पूर्व देने के लिए पथ में पका रहा है ।

वास्तव में कोई अन्य प्लेटफ़ॉर्म-स्वतंत्र "ऑपरेटिंग सिस्टम ... एक पंजीकृत कमांड के लिए पथ के बारे में जानकारी" नहीं है, इसलिए सबसे सरल बात यह है कि प्रदान किए जा रहे पथ पर जोर देना #!


0

मेरा मानना ​​है कि यदि आप चाहें या चाहें तो एक वैकल्पिक दुभाषिया निर्दिष्ट कर सकते हैं। उदाहरण के लिए:

#!/home/user/myrubyinterpreter

अधिक बार शेल स्क्रिप्ट के साथ देखा जाता है:

#!/bin/bash
#!/bin/sh
#!/bin/dash
#!/bin/csh

4
लेकिन यह जरूरी क्यों होगा? आप सीधे इनके साथ गहरे लाल रंग का चला सकते हैं ruby, लेकिन यह निर्दिष्ट करने से रोक नहीं है /home/user/myrubyinterpreterअगर आप चाहते हैं
माइकल Mrozek

माइकल की बात बिल्कुल वही है जो मैं पूछ रहा हूँ।
आरा

0

से क्लासिक शैल स्क्रिप्टिंग किताब:

शेल स्क्रिप्ट आम तौर पर के साथ शुरू #! /bin/sh। यदि आप /bin/shPOSIX अनुरूप नहीं है, तो एक POSIX- आज्ञाकारी खोल का पथ का उपयोग करें । कुछ निम्न स्तर के "गोच" भी हैं:

  • चलाने के लिए दुभाषिया के लिए आपको पूरा पथनाम जानना होगा। यह क्रॉस-वेंडर पोर्टेबिलिटी को रोक सकता है, क्योंकि विभिन्न विक्रेता अलग-अलग जगहों (जैसे, /bin/awkबनाम /usr/bin/awk) में चीजें डालते हैं ।

-2

अन्य कारण हैं, लेकिन सुरक्षा के दृष्टिकोण से मैं कभी नहीं चाहूंगा कि कोई स्क्रिप्ट सही रास्ते के बारे में धारणा बनाए। क्या होगा अगर यह गलत है और यह गलत शेल या दुभाषिया चलाता है? एक जिसे एक दुर्भावनापूर्ण उपयोगकर्ता द्वारा डाला गया है? या क्या होगा अगर यह किसी विशेष शेल पर निर्भर करता है और गलत शेल का उपयोग करने पर दुर्घटनाग्रस्त हो जाएगा?

उपयोगकर्ता अपने पथ के साथ गड़बड़ कर सकते हैं और सामान को तोड़ सकते हैं - उपयोगकर्ता पर भरोसा न करें :-) मैंने कई हमले किए हैं जो उपयोगकर्ता को अपने पथ के साथ गलत काम करने पर भरोसा करते हैं - आमतौर पर गलत क्रम में चीजें मिल रही हैं - इसलिए मैं पलटा कर सकता हूं एक सामान्य स्क्रिप्ट कॉल।

हां, मुझे पता है कि यदि आपने स्वयं स्क्रिप्ट लिखी है तो आप काफी हद तक यह दावा कर सकते हैं कि आपने अपना रास्ता खुद ही बना लिया है, लेकिन एक दुभाषिया उन फैसलों को नहीं कर सकता।


यह चिंता केवल तभी लागू होती है जब स्क्रिप्ट उन्नत विशेषाधिकार के साथ चल रही हो। और यह असामान्य है, क्योंकि शेबंग और सेटएक्सिड एक साथ अच्छी तरह से नहीं खेलते हैं, और इसके बारे में चिंता करने के लिए बहुत अधिक है $PATH। उन्नत विशेषाधिकार के बिना, यदि LD_PRELOADउपयोग किया जाता है तो क्या होगा ? PS डाउनवोटेड क्योंकि सुरक्षा के बारे में गलत चेतावनी देना सुरक्षा के लिए हानिकारक है।
गिलेस एसओ- बुराई को रोकना '

सैक्सीड के बारे में आपकी बात सर्वमान्य है, हालाँकि यह पूरी तरह से उपयोगी हमला वेक्टर है, इसलिए निश्चित रूप से गलत चेतावनी नहीं है
रोरी अलसॉप

1
क्या आप एक ऐसे मामले का उदाहरण दे सकते हैं जहां PATHएक हमला वेक्टर है, और इतने सारे अन्य हमले वैक्टर नहीं हैं कि पूरे दृष्टिकोण को पुनर्विचार किया जाना चाहिए?
गिलेस एसओ- बुराई को रोकना '

@ गिल्स - +1 आपके पास एक अच्छा बिंदु है, निश्चित रूप से, जैसे कि यह टूटा हुआ है शायद इसमें अन्य तरीके हैं जैसे कि मान्य हैं, हालांकि टूटी हुई चीजों के मामले में आप इसे ठीक कर सकते हैं, यह एक आसान है।
रोरी अलसॉप
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.