मैंने निम्नलिखित की कोशिश की, लेकिन यह काम नहीं करता है:
$ cat script.sh
#!/bin/env -i /bin/sh
/bin/env
$ script.sh
/bin/env: invalid option -- ' '
Try `/bin/env --help' for more information.
मैंने निम्नलिखित की कोशिश की, लेकिन यह काम नहीं करता है:
$ cat script.sh
#!/bin/env -i /bin/sh
/bin/env
$ script.sh
/bin/env: invalid option -- ' '
Try `/bin/env --help' for more information.
जवाबों:
इसका कारण यह नहीं है क्योंकि यह -i /bin/shएकल तर्क के रूप में देखता है env। आमतौर पर यह 2 तर्क होगा, -iऔर /bin/sh। यह सिर्फ शेबंग की एक सीमा है। इसके आसपास कोई रास्ता नहीं।
हालाँकि आप अभी भी इस कार्य को कर सकते हैं, बस एक अलग तरीके से।
यदि आप चाहते हैं कि यह कार्य स्क्रिप्ट द्वारा ही किया जाए, और ऐसा कुछ नहीं करना है env -i script.sh, तो आप स्क्रिप्ट को फिर से निष्पादित कर सकते हैं।
#!/bin/sh
[ -z "$CLEANED" ] && exec /bin/env -i CLEANED=1 /bin/sh "$0" "$@"
यदि स्क्रिप्ट CLEANEDपर्यावरण चर सेट नहीं है , तो यह स्क्रिप्ट को फिर से निष्पादित करने का कारण बनेगा । फिर से निष्पादित करने पर, यह सुनिश्चित करने के लिए चर सेट करता है कि यह लूप में नहीं जाता है।
envGNU कोरुटिल्स से अब -Sइस एक के समान मुद्दों को हल करने का एक विकल्प है, लेकिन बिल्कुल समान नहीं है। उदाहरण के लिए #!/usr/bin/env -S perl -T।
#!/usr/bin/env -S -i /bin/sh। पोर्टेबिलिटी के मुद्दों से अवगत रहें।
इसके साथ अपनी स्क्रिप्ट चलाएँ env -i:
env -i script.sh
और स्क्रिप्ट हमेशा की तरह:
#!/bin/sh
# ... your code here
यदि आपका मतलब साफ वातावरण के साथ दौड़ने से है तो स्पष्ट रूप से कहें कि जब आप दौड़ते हैं। एडुआर्डो इवानेक इस जवाब में कुछ विचार देता है , आप अपनी स्क्रिप्ट को execउस समय कॉल कर सकते हैं जब पर्यावरण साफ न हो (जैसे $ होम परिभाषित किया गया है):
[ "$HOME" != "" ] && exec -c $0
बैश के साथ, आप इसे इस तरह से कर सकते हैं:
#!/usr/bin/bash
set -e
set -u
[ -v HOME ] && exec -c "$0" "$@"
# continue with the rest of the script
# e.g. print the cleaned environment:
export
set -eऔर set -u आदेशों का कड़ाई से आवश्यक नहीं हैं, लेकिन मैं उन्हें प्रदर्शित करने के लिए है कि इस दृष्टिकोण (के रूप में उदाहरण के लिए सेट किए बिना चर तक पहुँचने पर निर्भर नहीं करता शामिल [ "$HOME" != "" ]होगा) और एक के साथ संगत है set -eसेटिंग।
HOMEवैरिएबल का परीक्षण सुरक्षित होना चाहिए क्योंकि बैश नॉन-इंटरैक्टिव मोड में स्क्रिप्ट निष्पादित करता है, अर्थात ~/.bashrcस्टार्टअप के दौरान कॉन्फ़िगरेशन फ़ाइलें जैसे (जहां पर्यावरण चर सेट किया जा सकता है) खट्टा नहीं होता है।
उदाहरण आउटपुट:
declare -x OLDPWD
declare -x PWD="/home/juser"
declare -x SHLVL="1"
लिनक्स 2-तर्क शेबंग लिमिटेशन (इंटरपीटर + एकल तर्क) अधिकांश उत्तरों में नोट किया गया है, लेकिन यह कहना कि यह नहीं किया जा सकता गलत है - आपको बस एक दुभाषिया में बदलने की आवश्यकता है जो एक एकल तर्क के साथ कुछ उपयोगी कर सकता है:
#!/usr/bin/perl -we%ENV=();exec "/bin/sh " . join " ", map "'$_'", @ARGV;
# your sh script here
यह क्या करता है perlएक-लाइनर स्क्रिप्ट ( -e) के साथ आह्वान किया जाता है जो स्पष्ट %ENV(से सस्ता env -i) और आह्वान करता है exec /bin/sh, सही ढंग से तर्कों को उद्धृत करता है। आगे perlतर्क जोड़े जा सकते हैं, यदि आवश्यक हो (हालांकि लिनक्स पर बहुत अधिक नहीं है क्योंकि आप BINPRM_BUF_SIZEवर्णों तक सीमित हैं , जिसकी संभावना 128 है)
अफसोस की बात है, यह लिनक्स विशिष्ट है, यह एक ऐसी प्रणाली पर काम नहीं करेगा जो कई शेबंग तर्क देता है: - /
perlइस स्ट्रिंग को एक एकल तर्क के रूप में संसाधित करता है, इसलिए इसे ऊपर उद्धृत नहीं किया गया है जैसा कि आप सामान्य रूप perl -e ...से कमांड लाइन से करेंगे (यदि आप इन उद्धरणों को जोड़ना चाहते थे जो संरक्षित हैं, तो पर्ल केवल एक शाब्दिक स्ट्रिंग देखता है, इस पर चेतावनी बेकार के बारे में शिकायत करेगा लगातार)।
यह भी ध्यान रखें कि इस तरह से इस्तेमाल किए जाने पर व्यवहार में थोड़ा बदलाव आता है, @ARGVआम तौर पर इसमें केवल तर्क होते हैं, और $0स्क्रिप्ट होती है, लेकिन इसके साथ ही शेबिंग $ARGV[0]स्क्रिप्ट का नाम है (और $0है -e) जो इसे थोड़ा आसान बनाता है।
आप इसे एक दुभाषिया के साथ भी हल कर सकते हैं कि -cप्राचीन एटी एंड टी पर इसकी कमांड लाइन (अतिरिक्त तर्क के बिना ) "पुनरावृत्ति करता है" ksh93:
#!/bin/ksh /usr/bin/env -i /bin/sh
हालांकि शायद kshआजकल उतना आम नहीं है ;-)
( bashइसके साथ एक समान विशेषता है --wordexp, लेकिन यह उन संस्करणों में "अनिर्धारित" है जहां यह काम करता है, और उन संस्करणों में संकलन समय पर सक्षम नहीं है जहां यह प्रलेखित है: - / इसके लिए भी इसका उपयोग नहीं किया जा सकता क्योंकि इसे दो तर्कों की आवश्यकता है। ..)
इसके अलावा, @Patrick और @ maxschlepzig के उत्तर पर प्रभावी रूप से भिन्नता:
#!/bin/bash
[ "$_" != bash ] && exec -c -a "bash" /bin/bash "$0" "$@"
# your script here
एक नए चर का उपयोग करने के बजाय यह विशेष " _" चर का उपयोग करता है , अगर यह बिल्कुल "bash" के लिए सेट नहीं है, तो स्क्रिप्ट को (और इसलिए ) सिर्फ "bash" बनाने के लिए execउपयोग -aकरें , और पर्यावरण को साफ करने के लिए उपयोग करें।ARGV[0]$_-c
वैकल्पिक रूप से, यदि यह स्क्रिप्ट की शुरुआत में पर्यावरण को साफ करने के लिए स्वीकार्य है (केवल बैश):
#!/bin/sh
unset $(compgen -e)
# your script here
compgenसभी निर्यात किए गए पर्यावरण चर के नामों को सूचीबद्ध करने और unsetउन्हें एक ही बार में उपयोग करने के लिए (पूरा सहायक) का उपयोग करता है ।
शेबंग व्यवहार की सामान्य समस्या के बारे में अधिक जानकारी के लिए शेबंग में कई तर्क भी देखें ।