আমি কীভাবে বিশ্বস্তভাবে প্যাট-এ কোনও প্রোগ্রামের পুরো পথটি খুঁজে পাব?


12

PATHশেল স্ক্রিপ্টটি ব্যবহার করে আমাকে একটি প্রদত্ত প্রোগ্রামের পথটি সন্ধান করতে হবে । পাথটি অবশ্যই প্রোগ্রামটির আসল পূর্ণ পাথ হতে হবে, যা পরবর্তীতে exec*কোনও একটি ফাংশনে যেতে পারে , যা PATHনিজে অনুসন্ধান করে না , যেমন execv

এখানে এমন প্রোগ্রাম রয়েছে killযা প্রকৃত প্রোগ্রাম এবং একই সাথে বিল্ট-ইন শেল হিসাবে উপলব্ধ। যদি এটি হয় তবে আমার আসল প্রোগ্রামটির পুরো পথ প্রয়োজন।

বেশ কয়েকটি ইউটিলিটি রয়েছে যেটি পজিক্স স্ট্যান্ডার্ডের কমান্ড সন্ধান এবং এক্সিকিউশন বিভাগ 2.9.1.1.1 অনুযায়ীPATH উল্লিখিতভাবে একটি প্রোগ্রাম সন্ধান করতে পারে ।

আছে which, যা কোনও মান অংশ নয়। এটি কিছু সিস্টেমে নিয়মিত প্রোগ্রাম হতে পারে, কিছু শাঁস এটি একটি অন্তর্নির্মিত সরবরাহ করে। এটি বেশিরভাগ সিস্টেমে এবং শেলগুলিতে উপলব্ধ বলে মনে হয় তবে বিল্টিন সংস্করণ সহ শেলগুলি কার্যনির্বাহী পথটির পরিবর্তে বিল্ট-ইনটির নাম দেয়। এছাড়াও এটি কোনওভাবেই মানসম্মত নয় এবং কোনও আউটপুট ফিরে আসতে পারে এবং বিভিন্ন বিকল্প গ্রহণ করতে পারে।

bash# which kill
/usr/bin/kill
dash# which kill
/usr/bin/kill
fish# which kill
/usr/bin/kill
mksh# which kill
/usr/bin/kill
tcsh# which kill
kill: shell built-in command.
zsh# which kill
kill: shell built-in command

এটি রয়েছে whenceযা কয়েকটি শেলের অন্তর্নির্মিত। তবে অনেক গুলিতে পাওয়া যায় না। এটি প্রোগ্রামে যাওয়ার পরিবর্তে বিল্ট-ইনটির নামটি ফিরিয়ে দেবে। একটি -pকোথা এই আচরণ পরিবর্তন করার জন্য প্রেরণ করা হতে পারে।

bash# whence kill
bash: whence: command not found
dash# whence kill
dash: 1: whence: not found
fish# whence kill
fish: Unknown command 'whence'
mksh# whence kill
kill
mksh# whence -p kill
/usr/bin/kill
tcsh# whence kill
whence: Command not found.
zsh# whence kill
kill
zsh# whence -p kill
/usr/bin/kill

এখানে commandপসিএক্স: ২০০৮ দ্বারা নির্মিত বিল্টিন রয়েছে । দুর্ভাগ্যক্রমে এটি নিয়মিত কমান্ড এবং বিল্ট-ইনগুলি অনুসন্ধান করে এবং একই নামের একটি অন্তর্নির্মিত ছায়া গোছানো প্রোগ্রামটির পাথের পরিবর্তে বিল্ট-ইনটির নাম ফিরিয়ে দেবে। কিছু পুরানো শেল এটি এখনও কার্যকর করেনি।

bash# command -v kill
kill
dash# command -v kill
kill
fish# command -v kill
/usr/bin/kill
mksh# command -v kill
kill
tcsh# command -v kill
command: Command not found.
zsh# command -v kill
kill

enableপসিক্সে নির্দিষ্ট করা আছে কিনা তা আমি বুঝতে পারি না তবে এটি যদি হয় তবে আপনি enable -n whichবিল্ট-ইন শেলটি অক্ষম করতে ব্যবহার করতে পারেন which
মুজার

এবং সেখানে রয়েছেrealpath
ইপুর সিরার

@ মুজার আমার হাতে থাকা শেলগুলিতে, enableকেবলমাত্র bashএবং সরবরাহ করেছেনzsh
সেবাস্তিয়ান শ্র্রেডার

1
আপনার নির্দিষ্ট স্কেলের জন্য একটি বাস্তব পদ্ধতি দরকার যা আপনার স্ক্রিপ্টটি সমস্ত শেলের জন্য নয়। স্ক্রিপ্টগুলি এলোমেলো শেল দ্বারা সম্পাদিত হয় না তবে বিশেষত শেবাং লাইনে নির্দিষ্ট শেল দ্বারা চালিত হয়। বলা হচ্ছে, বাশ যে হবে type -p। ব্যাশ এবং ড্যাশ উভয়ই আপনাকে commandএকই নামে কোনও ফাংশন বা বিল্টিন থাকা সত্ত্বেও প্রকৃত নির্বাহযোগ্য চালনার জন্য কমান্ড বলতে দেয় ।
অ্যালেক্সপি

1
@ অ্যালেক্সপ commandফাংশনগুলি এড়িয়ে যায় (এবং উপাধি) তবে বিল্টইনস নয়, যেমন প্রশ্নটি সঠিকভাবে বলেছে। এবং আপনি সর্বদা একটি শেবাং ব্যবহার করতে পারবেন না কারণ সমস্ত সিস্টেমে কোনও শেল, এমনকি কিছু পসিক্স শেল পাওয়া যায় এমন কোনও পাথ নেই।
dave_thompson_085

উত্তর:


11

এটি কেবল নিজের জন্য অনুসন্ধান করুন।

export IFS=":"
[ -z "${1}" ] && exit 1
for dir in $PATH
do if [ -x "${dir}/${1}" ]
   then echo "${dir}/${1}"
        exit 0
   fi
done
echo ${1} not found
exit 1

পরীক্ষিত bash, dash, ksh, mksh,zsh

হালনাগাদ

উপরেরটি একা স্ট্যান্ড স্ক্রিপ্টের জন্য দুর্দান্ত তবে আপনি যদি আরও বড় স্ক্রিপ্টে এম্বেড করার পরিকল্পনা করে থাকেন তবে নীচের মতো আরও কিছু ব্যবহার করতে পারেন।

function find_path() {
   IFS_SAVE="${IFS}"
   export IFS=":"
   [ -z "${1}" ] && exit 1
   for dir in $PATH
   do if [ -x "${dir}/${1}" ]
      then echo "${dir}/${1}"
           export IFS="${IFS_SAVE}"
           return 0
      fi
   done
   export IFS="${IFS_SAVE}"
   echo ${1} not found
   return 1
}

এই যাতে IFSম্যাচ, এছাড়াও আনা খোঁজার পর পুনঃস্থাপিত হলে exitএর সঙ্গে return'র


1
-এফ-এর পরিবর্তে -x?
জেফ শ্যাচলার

@ জেফ শ্যাচলার ভাল পয়েন্ট, অ-এক্সিকিউটেবল ফাইলগুলি বেছে নেওয়ার কোনও কারণ নেই।
জ্যাচারি ব্র্যাডি

3
যদি আপনি এটিকে বৃহত্তর শেল স্ক্রিপ্টে সংহত করে থাকেন (সম্ভবত এটির নিজের মতো করে একটি স্ক্রিপ্ট তৈরি করার বিপরীতে) তবে আপনি পরে আইএফএসের পুরানো মানটি পুনরুদ্ধার করতে চাইতে পারেন - অন্যথায় এটির প্রচুর প্রভাব থাকতে পারে স্ক্রিপ্টের বাকি
অংশগুলি

IFSচলকটি রফতানি কেন ? স্থানীয় শেলটিতে এই সেটটি রাখা কি যথেষ্ট নয়? স্থানীয় কথা বললে, local IFSপোর্টেবল হবে? অন্য কিছু যদি একইভাবে আইএফএস সংরক্ষণ করে তবে উপরেরগুলি দুর্বলভাবে ইন্টারঅ্যাক্ট করতে পারে। এ খুঁজছি দঃপূঃ উপর এই প্রশ্ন , localPOSIX না থাকা সত্ত্বেও অধিকাংশ শাঁস জন্য কাজ করতে পারে। মূল সংস্করণটি একটি (…)সাব-শেলের মধ্যে রেখে দেওয়াও কাজ করতে পারে।
এমভিজি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.