डबल हेफ़ेन (-) काम के साथ शुरू होने वाला यह शेबंग कैसे करता है?


14

मैंने रोसेटाकोड पृष्ठ में निम्नलिखित प्रकार के शेबंग पाए हैं:

--() { :; }; exec db2 -txf "$0"

यह Db2 के लिए काम करता है, और Postgres के लिए एक समान बात है। हालांकि, मुझे पूरी लाइन समझ में नहीं आती है।

मुझे पता है कि डबल डैश एसक्यूएल में एक टिप्पणी है, और उसके बाद यह डीबी 2 को कुछ मापदंडों के साथ फाइल के रूप में फ़ाइल को पारित करने के साथ निष्पादित करता है। लेकिन लघुकोष्ठक, घुंघराले ब्रैकेट, बृहदान्त्र और अर्ध-बृहदान्त्र के बारे में क्या है, और एक असली शेबंग को कैसे बदला जा सकता है #! ?

https://rosettacode.org/wiki/Multiline_shebang#PostgreSQL

जवाबों:


18

संबंधित: कौन सा शेल दुभाषिया एक स्क्रिप्ट चलाता है जिसमें कोई शेबंग नहीं है?

स्क्रिप्ट में एक शबंग / हैशबैंग / #!लाइन नहीं है, बस इसलिए कि डबल डैश नहीं है #!

हालांकि, स्क्रिप्ट को एक शेल द्वारा निष्पादित किया जाएगा (लिंक किए गए प्रश्न और उत्तरों के ऊपर देखें), और उस शेल में, यदि -फ़ंक्शन नाम में एक वैध चरित्र है, तो लाइन शेल फ़ंक्शन को घोषित करती है जिसे --कुछ भी नहीं कहा जाता है (ठीक है, यह चलता है :,) जो कुछ नहीं करता है ) और जिसे कभी नहीं बुलाया जाता है।

फ़ंक्शन, अधिक सामान्य बहु-पंक्ति संकेतन में (बस इसे और अधिक स्पष्ट करने के लिए कि यह कैसा दिखता है, जैसा कि इसका विषम नाम थोरा इस तथ्य को अस्पष्ट करता है कि यह वास्तव में एक फ़ंक्शन है):

-- () {
  :
}

फ़ंक्शन परिभाषा का एकमात्र उद्देश्य एक पंक्ति है जो एक शेल स्क्रिप्ट में मान्य है और एक ही समय में एक वैध SQL कमांड (एक टिप्पणी) है। इस तरह के कोड को पॉलीग्लॉट कहा जाता है ।

बोगस शेल फ़ंक्शन को घोषित करने के बाद, स्क्रिप्ट जब शेल स्क्रिप्ट दुभाषिया द्वारा निष्पादित की जाती है, execतो चालू शेल को चलाने के परिणामस्वरूप होने वाली प्रक्रिया के साथ बदल देती है db2 -txf "$0", जो db2 -txfकमांड लाइन से स्क्रिप्ट के पथनाम का उपयोग करने के समान होगा ।

यह तरकीब शायद उन प्रणालियों पर मज़बूती से काम नहीं करेगी जहाँ dashया अन्य- ashआधारित शेल, yashबोर्न शेल, ksh88या के ksh93रूप में उपयोग किया जाता है /bin/sh, क्योंकि ये शेल उन कार्यों को स्वीकार नहीं करते हैं जिनके नाम में डैश होते हैं।

यह भी संबंधित:


मुझे लगता है कि निम्नलिखित भी काम करेगा (वास्तव में परीक्षण नहीं):

--() { exec db2 -txf "$0"; }; --

@ilkachachu अब बेहतर है?
Kusalananda

1
अरे हाँ! और मुझे याद दिलाने के लिए धन्यवाद कि उस तरह की चीज को क्या कहा जाता है। :)
ilkkachu

6

जैसा कि @ कुसलानंद पहले ही कह चुके हैं, वह चाल टूट गई है और यह सभी गोले में काम नहीं करेगा।

यहाँ इसे लेने में मेरी बात है:

--/.. 2>/dev/null; exec db2 -txf "$0"

पहला आदेश विफल होना चाहिए भले ही एक फ़ाइल / निर्देशिका का नाम --वर्तमान निर्देशिका में मौजूद हो और किसी भी त्रुटि को बंद कर दिया जाएगा 2>/dev/null; शेल फिर दूसरी कमांड के साथ आगे बढ़ेगा exec


यह अभी भी वास्तव में पोर्टेबल नहीं है। यह एक मान्य स्क्रिप्ट नहीं है और आप अभी भी कॉलिंग शेल पर भरोसा कर रहे हैं कि इस तथ्य के इर्द-गिर्द काम करें कि कर्नेल स्क्रिप्ट को चलाने से इंकार कर देगा और ENOEXECयदि आप कोशिश करेंगे तो वापस आ जाएंगे । स्क्रिप्ट का उपयोग straceकरके देखने का प्रयास करें कि मेरा क्या मतलब है।
kasperd

@kasperd, यह अभी भी पोर्टेबल होना चाहिए, शेल को स्क्रिप्ट पर शेल स्क्रिप्ट के रूप में चलाना चाहिए, यदि exec()यह काम नहीं करता है। "यदि ENOEXEC [त्रुटि] के बराबर त्रुटि के कारण एफ़एलएल () फ़ंक्शन विफल हो जाता है, तो शेल कमांड कमांड को उसके पहले ऑपरेंड के रूप में आमंत्रित किए गए शेल के बराबर कमांड निष्पादित करेगा, ..." ( pubs.opengirc देखें .org / onlinepubs / 9699919799.2018edition / उपयोगिताओं /… )
ilkachachu

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

@kasperd, ठीक है, निश्चित रूप से, यह काम नहीं करेगा यदि आप exec()इसे सीधे शेल के अलावा किसी अन्य चीज़ से लेते हैं। लेकिन वह मामला क्या होगा? आप स्क्रिप्ट को cronइस तरह से चलाना चाहते हैं , लेकिन मुझे लगता है कि यह सब कुछ वैसे भी एक शेल के माध्यम से चलाता है, और यहां तक ​​कि अगर नहीं, तो db2 -txf /path/to/scriptउस मामले में बस वर्तनी आसान है , क्योंकि आपको केवल एक बार करने की आवश्यकता है। शॉर्टहैंड कार्य होने से ज्यादातर एक इंटरैक्टिव शेल पर उपयोगी होता है। लेकिन निश्चित रूप से, एक अलग आवरण स्क्रिप्ट अधिक मजबूत हो सकती है।
ilkkachu

1
@kasperd मैं आपको डॉक्स और मानकों से परेशान नहीं करूंगा; कर के देखो! echo 'int main(int c,char**a){execvp(a[1],a+1);}' | cc -include unistd.h -xc -; echo echo yeah > a.sh; chmod 755 a.sh; ./a.out ./a.sh; PATH=`pwd` ./a.out a.sh
चाचा बिली
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.