2012-09-13 18 views
10

मैंने होमब्री के माध्यम से rbenv स्थापित किया, और अब मुझे नहीं पता कि path_helper ने शुरुआत के बजाय पथ के अंत में ~/.rbenv/shims क्यों डाला। और सबसे महत्वपूर्ण बात यह है कि path_helper को यह जानकारी कैसे मिली?ओएस एक्स माउंटेन शेर: path_helper कैसे काम करता है?

path_helper के मैन पेज के अनुसार, यह/etc/पथ से प्रविष्टियों और /etc/paths.d में फ़ाइलों से पढ़ता है। लेकिन मुझे स्ट्रिंग ".rbenv/shims" नहीं मिल रहा है।

~% cat /etc/paths 
/usr/bin 
/bin 
/usr/sbin 
/sbin 
/usr/local/bin 
~% ls -la /etc/paths.d 
total 0 
drwxr-xr-x 2 root wheel 68 Jun 21 03:16 . 
drwxr-xr-x 107 root wheel 3638 Sep 10 09:59 .. 
~% /usr/libexec/path_helper 
PATH="/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/Users/gordon/.rbenv/shims"; export PATH; 

उत्तर

6

मुझे लगता है कि अपने .bash_profile या .bashrc अपने पथ पर .rbenv/shims जोड़ रहा है, और कहा कि इससे पहले कि path_helper खोल शुरू हुआ के दौरान शुरू हो जाती है कुछ बिंदु पर चल रहा है।

path_helper के लिए आदमी पृष्ठ खुल जाता है के साथ: यहां महत्वपूर्ण बिंदु

The path_helper utility reads the contents of the files in the directo- 
ries /etc/paths.d and /etc/manpaths.d and appends their contents to the 
PATH and MANPATH environment variables respectively. 

कि path_helper उपयोगिता करने का इरादा है एक मौजूदा PATH सेटिंग करने के लिए सामग्री जोड़ने के लिए, उन्हें बदलना नहीं है।

तो, (और वास्तविकता में, क्या यह वास्तव में करता है आगे जोड़ते सामग्री,, जो PATH चर के लिए मायने रखती है उन्हें नहीं जोड़ी जा ...) अगर मैं अपने PATH, सेटिंग उत्पन्न पर एक प्रवेश के साथ शुरू path_helper यह सुनिश्चित करेगा कि प्रविष्टि PATH पर जारी रहती है।

% echo $SHELL 
/bin/bash 
% uname 
Darwin 
% /usr/libexec/path_helper 
PATH="/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin"; export PATH; 
% PATH="" /usr/libexec/path_helper 
PATH="/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin"; export PATH; 
% PATH=foo /usr/libexec/path_helper 
PATH="/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:foo"; export PATH; 

ध्यान दें कि foo, अंतिम पंक्ति में मेरी पथ में शामिल किया गया यहां तक ​​कि हालांकि /etc/paths और /etc/paths.d/* की सामग्री को नहीं बदला है।

उसी समय, path_helper उपयोगिता भी डुप्लिकेट प्रविष्टियों के साथ पथ बनाने के लिए पर सावधान नहीं लगती है; यह /etc/paths और /etc/paths.d/* और वर्तमान PATH को संगत करने के बाद डुप्लिकेट प्रविष्टियों हटा देता है।

यह बाद का विवरण विशेष रूप से भ्रमित हो सकता है क्योंकि यह मूल PATH सेटिंग (!) की तुलना में प्रवेश पुनरीक्षण का कारण बन सकता है।

नीचे इस व्यवहार के कुछ उदाहरण दिए गए हैं: पहला मामला एक डुप्लिकेट foo हटाया जा रहा है। दूसरा और तीसरा मामला एंट्री रीडरिंग का वर्णन करता है: जेनरेटेड पीएटीएच दोनों मामलों में समान है, लेकिन तीसरे मामले में, /usr/bin प्रविष्टि foo और bar के बीच PATH के सामने से स्थानांतरित कर दी गई है। (यह डुप्लिकेट-एंट्री हटाने प्रविष्टियों के जोड़ों पर बस सरल स्ट्रिंग-मिलान पर आधारित प्रतीत होता है, जैसा कि नीचे चौथे मामले द्वारा चित्रित किया गया है जहां स्ट्रिंग /usr/bin/foo/ और bar के बीच बनी हुई है।)

% PATH=foo:foo /usr/libexec/path_helper 
PATH="/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:foo"; export PATH; 
% PATH=foo:bar /usr/libexec/path_helper 
PATH="/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:foo:bar"; export PATH; 
% PATH=foo:/usr/bin:bar /usr/libexec/path_helper 
PATH="/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:foo:bar"; export PATH; 
% PATH=foo/:/usr/bin/:bar /usr/libexec/path_helper 
PATH="/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:foo/:/usr/bin/:bar"; export PATH; 

अंत में, श्रेय देना जहाँ क्रेडिट कारण है: जबकि आदेश दृश्यों के सब से ऊपर अपने ही जांच का परिणाम है, मैं मूल रूप से path_helper के व्यवहार की जांच के लिए प्रेरित किया गया था टिप्पणी here पढ़ने के बाद , जो इंगित करता है कि path_helper पैरेंट प्रक्रिया द्वारा PATH पर्यावरण चर सेट का पुन: उपयोग करता है।

+1

यह इंगित करने के लिए धन्यवाद कि, दस्तावेज़ों का पालन करें, path_helper * पथ * प्रीपेन्ड करता है और डुप्लीकेट हटा देता है। – algal

6

पथ_हेपर मैन पेज गलत है। मैन पेज का कहना है कि path_helper पाथ पर /etc/paths.d जोड़ रहा है। लेकिन असल में, path_helper/etc/paths से सूची में /etc/paths.d को एपेंडेंडिंग कर रहा है और उसके बाद प्रभावी रूप से प्रीपेन्डिंग कर रहा है जिसके परिणामस्वरूप वास्तविक पूर्व-मौजूदा पथ (साथ ही उस सूची से ओवरराइड डुप्लिकेट के पथ को शुद्ध करना)।

सटीक होना करने के लिए, केवल उदाहरण के लिए पथ की बात कर रहा है, क्या यह करता है:

  1. पथों की सूची फ़ाइल/etc/रास्तों में
  2. APPEND यह पर रास्तों की सूची में पढ़ा निर्देशिका में फ़ाइलों को /etc/paths.d
  3. उत्परिवर्तित पथ चर सूची
  4. सूची पर संलग्न उत्परिवर्तित पथ चर के मूल्य में किसी भी आइटम हटाने के लिए
  5. सहेजें नए मार्ग के रूप में इस सूची

स्यूडोकोड में यह अलग तरीके से व्यक्त करने के लिए, क्या यह कर रहा है है:

  1. Newpath = पढ़ें (/ etc/पथ)
  2. Newpath = $ Newpath + संलग्न + पढ़ें (/etc/paths.d/ *)
  3. पथ = $ पथ -minus- $ Newpath
  4. Newpath = $ Newpath + संलग्न + $ पथ
  5. पथ = $ Newpath

इसके बारे में विश्वासघाती यह है कि, यदि आप मैन्युअल रूप से अपने पथ को कॉन्फ़िगर कर रहे हैं, तो शायद यह उन घटकों को जोड़ने के लिए है जो सिस्टम पथ घटकों को ओवरराइड करते हैं। यदि पथ_हेपर को कॉल करने पर कॉल किया जाता है, तो यह आपके पथ घटकों से पहले सिस्टम-व्यापी पथ घटकों को डालकर आपके परिवर्तनों को पूर्ववत कर देगा।

पथ सहायक कैसे अप्रत्याशित रूप से कॉल किया जाएगा? उदाहरण के लिए, इसे/etc/zshenv द्वारा बुलाया जाता है, जिसे हर बार जब आप एक zsh खोल शुरू करते हैं, चाहे वह सबशेल हो या किसी अन्य ऐप से emacs, या जो कुछ भी कहा जाता है, एक zsh उदाहरण कहा जाता है।

मैंने इसे ओपनराडर bug report on path_helper के रूप में अधिक विस्तार से लिखा है।

+0

यहां कोई सुधार करने का प्रयास है, अगर किसी को इसका उपयोग करने की तरह लगता है/इसे https://github.com/yb66/path_helper – iain

+0

पर ओएस एल कैपिटन में, 'path_helper' को'/etc/zprofile' में कहा जाता है '/ etc/zshenv', जो मैं तर्क दूंगा * बदतर * है। कम से कम '/ etc/zshenv' पहली चीज़ सोर्स की गई थी, इसलिए आप' ~/.zshenv' में सभी गोले (इंटरैक्टिव, गैर-इंटरैक्टिव) के लिए 'पथ' को ओवरराइड कर सकते थे। लेकिन चूंकि '/ etc/zprofile'' ~/.zshenv' के बाद सोर्स किया गया है, यदि आप इंटरैक्टिव और गैर-इंटरैक्टिव शैल के लिए एक ही 'पथ' चाहते हैं तो आपको '~/.zshenv' में किए गए संशोधनों को दोहराने के लिए मजबूर होना पड़ता है '~/.zprofile'। – rampion