मैंने निम्नलिखित की कोशिश की, लेकिन यह काम नहीं करता है:
$ 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
पर्यावरण चर सेट नहीं है , तो यह स्क्रिप्ट को फिर से निष्पादित करने का कारण बनेगा । फिर से निष्पादित करने पर, यह सुनिश्चित करने के लिए चर सेट करता है कि यह लूप में नहीं जाता है।
env
GNU कोरुटिल्स से अब -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
उन्हें एक ही बार में उपयोग करने के लिए (पूरा सहायक) का उपयोग करता है ।
शेबंग व्यवहार की सामान्य समस्या के बारे में अधिक जानकारी के लिए शेबंग में कई तर्क भी देखें ।