আমি নিম্নলিখিত চেষ্টা করেছিলাম কিন্তু এটি কাজ করে না বলে মনে হচ্ছে:
$ 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
জিএনইউ কোর্টিল থেকে এখন একইর -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" != "" ]
would) এবং একটি সঙ্গে সামঞ্জস্যপূর্ণ set -e
সেটিং।
HOME
ভেরিয়েবলটি পরীক্ষা করা নিরাপদ হওয়া উচিত কারণ ব্যাশ অ-ইন্টারেক্টিভ মোডে স্ক্রিপ্টগুলি কার্যকর করে, যেমন কনফিগারেশন ফাইলগুলি ~/.bashrc
(যেখানে পরিবেশের ভেরিয়েবলগুলি সেট করা যেতে পারে) প্রারম্ভকালে উত্সাহিত হয় না।
উদাহরণ আউটপুট:
declare -x OLDPWD
declare -x PWD="/home/juser"
declare -x SHLVL="1"
$ cat script.sh
#!/bin/env -i /bin/sh
দুঃখজনকভাবে এটি সেভাবে কাজ করবে না - লিনাক্স -i /bin/sh
একটি আর্গুমেন্টকে পাস করার জন্য বিবেচনা করে env
( শেবাং দেখুন )।
লিনাক্স 2-আর্গুমেন্ট শেবাং সীমাবদ্ধতা (ইন্টারপেইটার + সিঙ্গেল আর্গুমেন্ট) বেশিরভাগ উত্তরে উল্লিখিত হয়েছে, তবে এটি করা যায় না তা ভুল - আপনাকে কেবল একটি দোভাষীকে পরিবর্তন করতে হবে যা একক যুক্তির সাহায্যে দরকারী কিছু করতে পারে:
#!/usr/bin/perl -we%ENV=();exec "/bin/sh " . join " ", map "'$_'", @ARGV;
# your sh script here
এটি যা করে তা হ'ল perl
ওয়ান-লাইন স্ক্রিপ্ট ( -e
) যা ক্লিয়ার %ENV
(এর চেয়ে কম সস্তা env -i
) এবং অনুরোধ করে exec /bin/sh
সঠিকভাবে যুক্তি উদ্ধৃত করে with প্রয়োজনে আরও 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
, কিন্তু এটি "অনথিভুক্ত" সংস্করণ যেখানে এটি কাজ করে, এবং সংস্করণ যেখানে এটি নথিভুক্ত করা হয় কম্পাইল সময়ে সক্ষম করা আছে: - / এটা এই জন্য যেহেতু এটি দুটি আর্গুমেন্ট দরকার ব্যবহার করা যাবে না। ..)
এছাড়াও, কার্যকরভাবে @ পেট্রিক এবং @ ম্যাক্সচলেপজিগের জবাবগুলির একটি ভিন্নতা:
#!/bin/bash
[ "$_" != bash ] && exec -c -a "bash" /bin/bash "$0" "$@"
# your script here
বরং ব্যবহার তুলনায় নতুন পরিবর্তনশীল এই ব্যবহারের বিশেষ " _
" পরিবর্তনশীল, এটা ঠিক সেট না যদি "ব্যাশ" তাহলে স্ক্রিপ্ট প্রতিস্থাপন exec
ব্যবহার -a
করতে ARGV[0]
(এবং অত: পর $_
ব্যাশ ", এবং ব্যবহার করে) শুধু" -c
পরিবেশ পরিষ্কার।
বিকল্পভাবে, যদি স্ক্রিপ্টের শুরুতে পরিবেশ পরিষ্কার করা গ্রহণযোগ্য হয় (কেবলমাত্র বাশ):
#!/bin/sh
unset $(compgen -e)
# your script here
যা compgen
রফতানি করা সমস্ত পরিবেশের ভেরিয়েবলের নাম তালিকাভুক্ত করতে (সম্পূর্ণরূপে সহায়তাকারী) ব্যবহার করে এবং unset
সেগুলি একবারে যায়।
শেবাং আচরণের সাধারণ সমস্যা সম্পর্কে আরও বিশদ জানতে শেবাংয়ের একাধিক যুক্তি দেখুন ।