$ PATH में डुप्लिकेट प्रविष्टियाँ एक समस्या है?


45

मैं अपने कुछ दोस्तों का bashrc स्रोत हूं। इसलिए मैं अपने $ PATH चर में डुप्लिकेट प्रविष्टियों को समाप्त करता हूं। मुझे यकीन नहीं है कि शुरू होने में लंबे समय तक आदेशों के लिए यही समस्या है। $ PATH आंतरिक रूप से कैसे काम करता है? क्या अधिक PATHS मेरे स्टार्ट अप को धीमा करता है?




जवाबों:


42

अधिक प्रविष्टियाँ होने $PATHसे आपका स्टार्टअप सीधे धीमा नहीं होता है, लेकिन यह हर बार धीमा करता है जब आप पहली बार शेल सत्र में एक विशेष कमांड चलाते हैं (हर बार जब आप कमांड चलाते हैं, क्योंकि बैश एक कैश रखता है)। जब तक आपके पास विशेष रूप से धीमी फाइलसिस्टम (जैसे एनएफएस, सांबा या अन्य नेटवर्क फाइलसिस्टम, या सिग्विन पर) है, तब तक मंदी शायद ही कभी बोधगम्य हो।

डुप्लिकेट प्रविष्टियाँ भी थोड़ी परेशान करती हैं जब आप अपनी $PATHदृष्टि की समीक्षा करते हैं , तो आपको अधिक cruft के माध्यम से उतारा करना होगा।

डुप्लिकेट प्रविष्टियों को जोड़ने से बचने के लिए यह काफी आसान है।

case ":$PATH:" in
  *":$new_entry:"*) :;; # already there
  *) PATH="$new_entry:$PATH";; # or PATH="$PATH:$new_entry"
esac

साइड नोट: किसी और के शेल स्क्रिप्ट को सोर्स करने का मतलब कोड को निष्पादित करना है जो उसने लिखा है। दूसरे शब्दों में, आप जब चाहें अपने दोस्तों को अपने खाते तक पहुंच प्रदान कर सकते हैं।

साइड नोट: .bashrcसेट $PATHया किसी अन्य पर्यावरण चर के लिए सही जगह नहीं है । पर्यावरण चर में स्थापित किया जाना चाहिए ~/.profile। देखें कि बैश के साथ पर्यावरण चर स्थापित करने के लिए कौन सी सेटअप फ़ाइलों का उपयोग किया जाना चाहिए? , .Bashrc और .bash_profile के बीच अंतर


8
+1: इस बात पर जोर नहीं दिया जा सकता है कि "अपने मित्रों को आपके खाते तक पहुंच प्रदान करें" पर्याप्त जोर। यहां तक ​​कि अगर आपको नुकसान पहुंचाने का कोई प्रयास नहीं है, तो उनकी स्क्रिप्ट सिर्फ वही हो सकती है जिसकी उन्हें जरूरत है और जब आप इसे स्रोत करते हैं तब भी अपना दोपहर का भोजन खाते हैं।
msw

इस समाधान के साथ एक संभावित मुद्दा यह है कि $ new_entry पहले ही PATH में पहली प्रविष्टि है, ": $ new_entry:" मेल नहीं खाएगा। मैंने प्रारंभिक ':' कॉलन को छोड़कर अपनी प्रोफ़ाइल में इसे ठीक किया।
जेफ बाउर

@JeffBauer मुझे समस्या नहीं दिख रही है। मैं उपयोग करता हूं case :$PATH:और case $PATHइसलिए नहीं कि यह मेल खाता है भले ही प्रवेश पहले या अंतिम हो।
गाइल्स का SO-

31

मैंने देखा है कि लोग अपने पैट वैरिएबल से डुप्लिकेट को साफ करते हैं awkऔर कुछ इस तरह से उपयोग करते हैं:

PATH=$(printf "%s" "$PATH" | awk -v RS=':' '!a[$1]++ { if (NR > 1) printf RS; printf $1 }')

आप इसे अपने bashrc में जोड़ने का प्रयास कर सकते हैं और सुनिश्चित करें कि आप अन्य फ़ाइलों को चलाने से पहले कहीं और स्रोत बना लें।

एक वैकल्पिक उपयोग करने के लिए किया जाएगा उपयोगिता।pathmerge

आपकी गति समस्या के रूप में, यह किसी भी महत्वपूर्ण तरीके से शेल के स्टार्टअप समय को प्रभावित नहीं करेगा, लेकिन यह कमांड के लिए टैब को पूरा करने में कुछ समय बचा सकता है, खासकर जब कमांड पथ में नहीं मिलता है और यह उसी के माध्यम से बार-बार खोज करता है फ़ोल्डर्स इसे खोज रहे हैं।

सुरक्षा पर एक नोट: आप चाहिए वास्तव में ध्यान गाइल्स 'चेतावनी सुरक्षा के बारे में यहाँ। किसी अन्य उपयोगकर्ता के स्वामित्व वाली फ़ाइल को सोर्स करके आप उन उपयोगकर्ताओं को अपने कोड को निष्पादित करने के लिए नि: शुल्क पास दे रहे हैं जो हर बार जब आप शेल शुरू करते हैं। यदि आप अपने पासवर्ड के साथ उन उपयोगकर्ताओं पर भरोसा नहीं करते हैं, तो आपको उनकी शेल फ़ाइलों को सोर्स नहीं करना चाहिए।


6
मुझे awk वन-लाइनर पसंद है, लेकिन यह एक अनुगामी ORS ':' प्रिंट करता है। इसलिए मैंने इसे पढ़ने के लिए संशोधित कियाPATH=$(echo "$PATH" | awk -v RS=':' -v ORS=":" '!a[$1]++{if (NR > 1) printf ORS; printf $a[$1]}')
gkb0986

अनुगामी :न केवल एक कॉस्मेटिक मुद्दा है। यह .आपके रास्ते में जोड़ने के समान है, जो संभावित रूप से खतरनाक है।
वारबीस

मैंने gkb0986 से फिक्स को शामिल करने के लिए उत्तर संपादित किया है।
टिम लेशर

@TimLesher मेरे द्वारा उत्तर के कारण संपादित नहीं किए जाने का कारण यह है कि यह मेरे लिए काम नहीं करता है .... और मूल इसके बिना काम करता है ( एक अनुगामी विभाजक को छोड़कर नहीं । मुझे नहीं पता कि क्या अंतर है। ।
कालेब

1
@ gkb0986 यह समाधान अभी भी विफल रहता है यदि पथ में कोई बचा हुआ स्थान है, जैसे PATH = / bin: / foo \ bar: / usr / bin। मुझे एक ऐसा संस्करण मिला, जो इसे unix.stackexchange.com/a/124517/106102
maharvey67

13

टाइपिंग कम से कम करने के लिए @Gilles उत्तर के आधार पर आप इसे एक फ़ंक्शन में लपेट सकते हैं:

function addToPATH {
  case ":$PATH:" in
    *":$1:"*) :;; # already there
    *) PATH="$1:$PATH";; # or PATH="$PATH:$1"
  esac
}

addToPATH /Applications/AIRSDK_Compiler/bin
addToPATH ~/.local/lib/npm/bin

1
सबसे व्यावहारिक रूप से प्रयोग करने योग्य (उच्च-स्तरीय, शायद) उत्तर।
.जोसफ

3

केवल पहले मैच को $PATHही निष्पादित किया जाता है, इसलिए उसके बाद की कोई भी प्रविष्टि संसाधित नहीं होती है। इसीलिए आपको कभी-कभी $PATHअपने वातावरण को अपेक्षित बनाने के लिए प्रविष्टियों के क्रम को संशोधित करना चाहिए ।

आपके प्रश्न का उत्तर देने के लिए: यह धीमे स्टार्टअप का कारण नहीं होना चाहिए।


1
लेकिन जब मैं एक कमांड टाइप करता हूं जो मौजूद नहीं है, तो इसमें अधिक समय लगता है। यह कमांड के लिए एक ही फोल्डर को दो बार सर्च करेगा।
बाल्की

@balki आप के साथ एक कमांड को पूरा करने का मतलब है TAB? उस मामले में आपको जांचना चाहिए कि क्या आप पूरी परिभाषा की तरह नहीं दिखते हैं complete -c which -a। आपको -aपैरामीटर को हटाना चाहिए । आप कमांड जारी करके इसे देख सकते हैं complete | grep which:।
राजेश

यह अभी भी एक मुद्दा हो सकता है अगर यह उसी निर्देशिका को खोजता है जो इसे खोजने से पहले कई बार में नहीं है।
रैंडम 832

-1

अपने PATH में डुप्लिकेट प्रविष्टियों को रोकने के लिए, मुझे निम्नलिखित को BOTH ~ / .bash_profit और ~ / .bashrc में डालना होगा:

PATH=$(echo $(sed 's/:/\n/g' <<< $PATH | sort | uniq) | sed -e 's/\s/':'/g')

मुख्य दोष यह है कि यह पैठ प्रविष्टियों को सॉर्ट करता है, लेकिन मुझे लगता है कि मैं इसके साथ रह सकता हूं।


PATH खोज का क्रम बहुत महत्वपूर्ण है।
स्टीवन शॉ
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.