मैं PATH पर किसी कार्यक्रम का पूरा रास्ता कैसे ढूंढूं?


12

मुझे PATHशेल स्क्रिप्ट का उपयोग करके किसी दिए गए प्रोग्राम का मार्ग खोजने की आवश्यकता है । पथ कार्यक्रम का वास्तविक पूर्ण पथ होना चाहिए, जिसे बाद में किसी एक exec*कार्य के लिए पारित किया जा सकता है , जो PATHस्वयं की खोज नहीं करता है, जैसे execv

ऐसे कार्यक्रम हैं kill, जो एक वास्तविक कार्यक्रम और एक ही समय में निर्मित शेल के रूप में उपलब्ध हैं। यदि यह मामला है, तो मुझे वास्तविक कार्यक्रम के लिए पूर्ण पथ की आवश्यकता है।

कई उपयोगिताओं हैं जो कि 2.9 2.9.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

वहाँ commandPOSIX द्वारा निर्दिष्ट बिलिन है: 2008 । दुर्भाग्य से यह नियमित कमांड और बिल्ट-इन की भी खोज करता है और उसी नाम के बिल्ट-इन द्वारा छायांकित प्रोग्राम के पथ के बजाय बिल्ट-इन का नाम लौटाएगा। कुछ पुराने गोले इसे अभी तक लागू नहीं किए हैं।

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क्या POSIX में निर्दिष्ट है या नहीं, लेकिन यदि यह है, तो आप enable -n whichशेल के लिए निर्मित शेल को अक्षम करने के लिए उपयोग कर सकते हैं which
मुजेर

और वहाँ हैrealpath
Ipor Sircer

@ मेज़र मेरे पास मेरे पास मौजूद गोले पर है, enableकेवल द्वारा प्रदान किया गया है bashऔरzsh
सेबस्टियन श्रैडर

2
आपको विशिष्ट शेल के लिए एक वास्तविक विधि की आवश्यकता होती है जो आपकी स्क्रिप्ट को सभी शेल के लिए नहीं चला रहा है । लिपियों को एक यादृच्छिक शेल द्वारा निष्पादित नहीं किया जाता है, लेकिन विशेष रूप से शेलबैंग लाइन में निर्दिष्ट शेल द्वारा। यह कहा जा रहा है, को मारना होगा type -p। बैश और डैश दोनों आपको commandकमांड को वास्तविक निष्पादन योग्य चलाने के लिए कहते हैं, भले ही उसी नाम से कोई फ़ंक्शन या बिलिन हो।
एलेक्सपी

1
@ AlexP commandकार्य (और उपनाम) को छोड़ देता है, लेकिन नहीं बनता है, जैसा कि Q सही कहता है। और आप हमेशा एक शेलबैंग का उपयोग नहीं कर सकते हैं क्योंकि कोई भी रास्ता नहीं है जो सभी सिस्टम पर किसी भी दिए गए शेल, या यहां तक ​​कि कुछ पॉस्क शेल भी मिलता है।
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}" ] && return 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 के बजाय -x?
जेफ स्कालर

@JeffSchaller अच्छा बिंदु, गैर-निष्पादन योग्य फ़ाइलों को चुनने का कोई कारण नहीं।
ज़ाचरी ब्रैडी

3
यदि आप इसे एक बड़ी शेल स्क्रिप्ट में एकीकृत करते हैं (जैसा कि इसे अपने आप में एक स्क्रिप्ट में बनाने का विरोध किया जाता है, जैसा कि संभवतः इरादा है), तो आप बाद में IFS के पुराने मूल्य को पुनर्स्थापित करना चाह सकते हैं - अन्यथा उस पर बहुत अधिक प्रभाव पड़ सकता है। बाकी की स्क्रिप्ट ...
Psmears

IFSचर का निर्यात क्यों ? क्या स्थानीय शेल में यह सेट होना पर्याप्त नहीं है? स्थानीय की बात, local IFSपोर्टेबल होगा ? अगर कुछ और इसी तरह से IFS को बचा रहा है तो उपरोक्त खराब तरीके से इंटरैक्ट कर सकता है। एसई पर इस सवाल को देखते हुए , localज्यादातर गोले POSIX नहीं होने के बावजूद काम कर सकते हैं। मूल संस्करण को एक (…)सबशेल में रखकर भी काम किया जा सकता है।
20
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.