সর্বাধিক সাধারণ ক্ষেত্রে $0
স্ক্রিপ্টের সাথে নিখুঁত বা আপেক্ষিক কোনও পথ থাকবে
script_path=$(readlink -e -- "$0")
(ধরে নিলাম একটি readlink
কমান্ড রয়েছে এবং এটি সমর্থন করে -e
) সাধারণত স্ক্রিপ্টের আর্জনিক পরম পথটি পাওয়ার জন্য যথেষ্ট ভাল উপায়।
$0
দোভাষীকে দেওয়া হিসাবে স্ক্রিপ্ট নির্দিষ্ট করে যুক্তি থেকে নির্ধারিত হয়।
উদাহরণস্বরূপ, এতে:
the-shell -shell-options the/script its args
$0
পায় the/script
।
আপনি যখন চালান:
the/script its args
আপনার শেলটি এটি করবে:
exec("the/script", ["the/script", "its", "args"])
যদি স্ক্রিপ্টে #! /bin/sh -
উদাহরণস্বরূপ সে-ব্যাং থাকে তবে সিস্টেমটি এটিকে রূপান্তর করবে:
exec("/bin/sh", ["/bin/sh" or "the/script", "-", "the/script", "its", "args"])
(যদি এতে শিট-ব্যাং না থাকে বা আরও সাধারণভাবে যদি সিস্টেম কোনও ENOEXEC ত্রুটি ফিরিয়ে দেয় তবে তা আপনার শেলটি একই কাজ করবে)
কিছু সিস্টেমে সেটুইড / সেটগিড স্ক্রিপ্টগুলির ব্যতিক্রম রয়েছে, যেখানে সিস্টেমটি কিছুতে স্ক্রিপ্টটি খুলবে এবং তার fd
x
পরিবর্তে চালাবে:
exec("/bin/sh", ["/bin/sh" or "the/script", "-", "/dev/fd/x", "its", "args"])
জাতি শর্ত এড়ানোর জন্য (যার ক্ষেত্রে $0
এটি অন্তর্ভুক্ত থাকবে /dev/fd/x
)।
এখন, আপনি তর্ক করতে পারে যে /dev/fd/x
হয় স্ক্রিপ্ট অবশ্যই এমন একটি পথ। তবে মনে রাখবেন যে আপনি যদি পড়ে থাকেন তবে আপনি $0
ইনপুটটি গ্রাস করার সাথে সাথে স্ক্রিপ্টটি ভেঙে ফেলবেন।
এখন, একটি পার্থক্য আছে যদি স্ক্রিপ্ট কমান্ড নাম হিসাবে অনুরোধ করা স্ল্যাশ না থাকে। ভিতরে:
the-script its args
তোমার শেল আপ দেখবে the-script
মধ্যে $PATH
। $PATH
কিছু ডিরেক্টরিতে পরম বা আপেক্ষিক (খালি স্ট্রিং সহ) পাথ থাকতে পারে। উদাহরণস্বরূপ, যদি বর্তমান ডিরেক্টরীটিতে $PATH
থাকে /bin:/usr/bin:
এবং the-script
এটি পাওয়া যায় তবে শেলটি এটি করবে:
exec("the-script", ["the-script", "its", "args"])
যা হয়ে যাবে:
exec("/bin/sh", ["/bin/sh" or "the-script", "-", "the-script", "its", "args"]
বা যদি এটিতে পাওয়া যায় /usr/bin
:
exec("/usr/bin/the-script", ["the-script", "its", "args"])
exec("/bin/sh", ["/bin/sh" or "the-script" or "/usr/bin/the-script",
"-", "/usr/bin/the-script", "its", "args")
উপরের সেতুগুলিতে সেটুইড কর্নার কেস বাদে $0
স্ক্রিপ্টের জন্য একটি পথ (পরম বা আপেক্ষিক) থাকবে।
এখন, একটি স্ক্রিপ্ট এ হিসাবেও বলা যেতে পারে:
the-interpreter the-script its args
the-script
উপরের হিসাবে যখন স্ল্যাশ অক্ষর নেই, আচরণটি শেল থেকে শেল থেকে কিছুটা পৃথক হয়।
পুরাতন এটিএন্ডটি ksh
বাস্তবায়নগুলি প্রকৃতপক্ষে নিঃশর্তভাবে স্ক্রিপ্টটি সন্ধান $PATH
করছিল (যা প্রকৃতপক্ষে একটি বাগ এবং সেটুইড স্ক্রিপ্টগুলির জন্য সুরক্ষা ছিদ্র ছিল) সুতরাং বর্তমান ডিরেক্টরিটিতে সন্ধানের সন্ধান না পাওয়া পর্যন্ত প্রকৃতপক্ষে স্ক্রিপ্টের কোনও পথ $0
ছিল না ।$PATH
the-script
বর্তমানের ডিরেক্টরিতে এটি পাঠযোগ্য হয় তবে নতুন এটিএন্ডটি ksh
চেষ্টা করবে এবং ব্যাখ্যা the-script
করবে। যদি তা না হয় এটি একটি পাঠযোগ্য জন্য অনুসন্ধান করবে এবং এক্সিকিউটেবল the-script
মধ্যে $PATH
।
কারণ bash
এটি পরীক্ষা করে যে the-script
এটি বর্তমান ডিরেক্টরিতে রয়েছে (এবং এটি কোনও ভাঙা সিমলিংক নয়) এবং যদি না হয় তবে এটিতে পাঠযোগ্য (প্রয়োজনীয়ভাবে নির্বাহযোগ্য নয়) the-script
অনুসন্ধান করা হবে $PATH
।
zsh
মধ্যে sh
এমুলেশন মত করবেন bash
ব্যতীত যে যদি the-script
বর্তমান ডিরেক্টরির মধ্যে একটি ভাঙা সিমবলিক লিঙ্ক, এটা একটা অনুসন্ধান করবে না the-script
এ $PATH
এবং পরিবর্তে একটি ত্রুটি প্রতিবেদন হবে।
বোর্ন-এর মতো অন্যান্য শেলগুলি সন্ধান the-script
করে না $PATH
।
এই সমস্ত শেলের জন্য যাইহোক, যদি আপনি দেখতে পান যে এটিতে $0
একটি নেই /
এবং পাঠযোগ্য নয়, তবে সম্ভবত এটি সন্ধান করা হবে $PATH
। তারপরে, ফাইলগুলি যেমন $PATH
সম্পাদনযোগ্য হওয়ার সম্ভাবনা থাকে, সম্ভবত এটির নিরাপদ সন্ধানের জন্য command -v -- "$0"
এটির সন্ধানের জন্য ব্যবহার করা (যদিও এটি $0
শেল বিল্টিন বা কীওয়ার্ডের নাম (বেশিরভাগ শেলগুলিতে) হয়ে থাকে তবে এটি কাজ করবে না )।
সুতরাং আপনি যদি সত্যিই সেই কেসটি কভার করতে চান তবে আপনি এটি লিখতে পারেন:
progname=$0
[ -r "$progname" ] || progname=$(
IFS=:; set -f
for i in ${PATH-$(getconf PATH)}""; do
case $i in
"") p=$progname;;
*/) p=$i$progname;;
*) p=$i/$progname
esac
[ -r "$p" ] && exec printf '%s\n' "$p"
done
exit 1
) && progname=$(readlink -e -- "$progname") ||
progname=unknown
(এতে ""
সংযুক্তি $PATH
হ'ল শেলগুলির সাহায্যে একটি পেছনের ফাঁকা উপাদান সংরক্ষণ করা হবে যার বিভাজক পরিবর্তে ডিলিমিটার$IFS
হিসাবে কাজ করে )।
এখন, আরও স্ক্রিপ্ট আহ্বান করার আরও রহস্যজনক উপায় রয়েছে। একজন করতে পারেন:
the-shell < the-script
বা:
cat the-script | the-shell
সেক্ষেত্রে, $0
প্রথম আর্গুমেন্ট (হতে হবে argv[0]
) যে ব্যাখ্যাকারী পেয়েছি (উপরে the-shell
, কিন্তু যে কোন কিছুই হতে পারে যদিও সাধারণভাবে পারেন basename বা যে ব্যাখ্যাকারী এক পথ)।
মানটির ভিত্তিতে আপনি সেই পরিস্থিতিতে আছেন তা সনাক্ত করা $0
নির্ভরযোগ্য নয়। আপনি ps -o args= -p "$$"
একটি ক্লু পেতে আউটপুট তাকান পারে । পাইপের ক্ষেত্রে, আপনি স্ক্রিপ্টের পথে ফিরে যেতে কোনও আসল উপায় নেই।
এক এছাড়াও করতে পারে:
the-shell -c '. the-script' blah blih
তারপর, ছাড়া zsh
(এবং বোর্ন শেলের কিছু পুরানো বাস্তবায়ন), $0
হবে blah
। আবার, সেই শেলগুলিতে স্ক্রিপ্টের পথে যাওয়া শক্ত hard
বা:
the-shell -c "$(cat the-script)" blah blih
প্রভৃতি
আপনার অধিকার রয়েছে তা নিশ্চিত করার জন্য $progname
আপনি এটিতে একটি নির্দিষ্ট স্ট্রিংয়ের জন্য অনুসন্ধান করতে পারেন:
progname=$0
[ -r "$progname" ] || progname=$(
IFS=:; set -f
for i in ${PATH-$(getconf PATH)}:; do
case $i in
"") p=$progname;;
*/) p=$i$progname;;
*) p=$i/$progname
esac
[ -r "$p" ] && exec printf '%s\n' "$p"
done
exit 1
) && progname=$(readlink -e -- "$progname") ||
progname=unknown
[ -f "$progname" ] && grep -q 7YQLVVD3UIUDTA32LSE8U9UOHH < "$progname" ||
progname=unknown
তবে আবার আমি মনে করি না যে এটি প্রচেষ্টাটির পক্ষে মূল্যবান।
$0
স্ক্রিপ্ট ব্যতীত অন্য কিছু রয়েছে যা প্রশ্নের শিরোনামের উত্তর দেয়। তবে, আমি$0
স্ক্রিপ্ট নিজেই এমন পরিস্থিতিতে আগ্রহী , তবে ডিরেক্টরিটি অন্তর্ভুক্ত করে না। বিশেষত, আমি এসও উত্তরে মন্তব্যটি বোঝার চেষ্টা করছি।