एक लंबे $ PATH को संपादित करने का एक और आरामदायक तरीका?


35

मैं जोड़ना चाहता हूं, ~ / .bashrc में, मेरी $ PATH के लिए कुछ निर्देशिकाएं।

मेरा $ PATH काफी लंबा है, इसलिए यह देखना थोड़ा कठिन है कि इसमें क्या निर्देशिकाएं हैं और किस क्रम में हैं।

मुझे पता है कि मैं अपने ~ / .bashrc को संशोधित कर सकता हूं:

PATH=$PATH:/some/dir
PATH=$PATH:/another/dir:/yet/another
PATH=$PATH:/and/another
...

इसे पढ़ना आसान होगा। लेकिन मैं सोच रहा था कि अगर पिछले वर्षों के दौरान बैश ने कुछ सिंटैक्स का अधिग्रहण किया है जो एक लंबे पैट को आसान बनाता है। जैसे, मैं एक वाक्य रचना के बारे में कल्पना कर रहा हूँ:

PATH=:((
  /some/dir
  /another/dir
  /yet/another
  /and/another
  ...
))

मुझे पता है कि ऐसा सिंटैक्स अमान्य है। मैं सोच रहा था कि क्या कुछ आसान है। है?


पथ के माध्यम से सेट करने के लिए पारंपरिक ट्यूटोरियल PATH=foo:$PATHगलत लगता है क्योंकि यह हर बार विकास को बनाए रखता है source ~/.bashrcऔर यहां तक ​​कि exec bashइसके बाद से मदद नहीं कर सकता $PATHहै export
林果

जवाबों:


25

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

  • add_path PATH चर के अंत में प्रविष्टि जोड़ देगा
  • प्री_पैथ पाथ चर की शुरुआत में प्रवेश को जोड़ देगा
  • del_path PATH चर से प्रविष्टि को हटा देगा, जहाँ भी यह है

यदि आप एक चर को दूसरे तर्क के रूप में निर्दिष्ट करते हैं, तो वह PATH के बजाय इसका उपयोग करेगा।

सुविधा के लिए, वे यहाँ हैं:

# is $1 missing from $2 (or PATH) ?
no_path() {
    eval "case :\$${2-PATH}: in *:$1:*) return 1;; *) return 0;; esac"
}
# if $1 exists and is not in path, append it
add_path () {
  [ -d ${1:-.} ] && no_path $* && eval ${2:-PATH}="\$${2:-PATH}:$1"
}
# if $1 exists and is not in path, prepend it
pre_path () {
  [ -d ${1:-.} ] && no_path $* && eval ${2:-PATH}="$1:\$${2:-PATH}"
}
# if $1 is in path, remove it
del_path () {
  no_path $* || eval ${2:-PATH}=`eval echo :'$'${2:-PATH}: |
    sed -e "s;:$1:;:;g" -e "s;^:;;" -e "s;:\$;;"`
}

यदि आप अपने bash स्टार्टअप फ़ाइल में उन्हें जोड़ते हैं, तो आप अपने PATH को इस तरह जोड़ सकते हैं:

pre_path $HOME/bin
add_path /sbin
add_path /usr/sbin

या एक अलग चर निर्दिष्ट करें:

pre_path $HOME/man MANPATH
pre_path $HOME/share/man MANPATH
add_path /usr/local/man MANPATH
add_path /usr/share/man MANPATH

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

और चूंकि ये फ़ंक्शन हैं, आप उन्हें कमांड लाइन से अंतःक्रियात्मक रूप से उपयोग कर सकते हैं, जैसे add_path $(pwd)कि वर्तमान निर्देशिका को पथ में जोड़ने के लिए कहकर ।


धन्यवाद। मैंने आपका कोड जाँच लिया है और यह काम करता है। हैरानी की बात यह है कि मुझे del_path (A "के लिए भी उपयोग मिला।" कुछ स्थितियों में मेरे PATH में ढोंगी, शैतान को कहां से पता है, इसलिए मैंने किया del_path .)।
निकोलो एम।

नमस्ते। bashrc स्क्रिप्ट से इस pathfuncs को स्रोत (शामिल) करना संभव है या क्या मुझे उन्हें वहां कॉपी / पेस्ट करना चाहिए?
क्रिस्टियानो

@ क्रिसटनो या तो काम करेगा। यह वास्तव में आप पर निर्भर है।
स्टारफिश

11

ठीक है, मुझे निम्नलिखित समाधान का पता चला है, जो मुझे लगता है कि सुरुचिपूर्ण है (जहां तक ​​शेल सिंटैक्स जाना है)। यह बैश के सरणी सिंटैक्स का उपयोग करता है और तत्वों में शामिल होने का एक साफ तरीका भी है :

paths=(
  /some/dir
  /another/dir
  '/another/dir with spaces in it'
  /yet/another
  /and/another
  /end
)
paths_joined=$( IFS=: ; echo "${paths[*]}" )

PATH=$paths_joined:$PATH

चेतावनी!

यह पता चला है कि इस समाधान में एक समस्या है : @terdon और @Starfish के समाधानों के विपरीत, यह पहले यह जांच नहीं करता है कि पथ पहले से ही पथ में हैं या नहीं। इसलिए, चूंकि मैं इस कोड को ~ / .bashrc में डालना चाहता हूं (और ~ / .profile में नहीं), डुप्लिकेट पथ पेट में रेंगना होगा। तो इस समाधान का उपयोग न करें (जब तक कि आप इसे ~ / .profile में न डालें (या, बेहतर, ~ / .bash_profile क्योंकि इसमें बैश विशिष्ट वाक्यविन्यास है))।


1
बहुत अच्छा। क्या आप एक उत्तर को स्वीकार कर सकते हैं ताकि अन्य लोग यहां समाधान पेश करने के लिए न आएं जब आप पहले से ही एक मिल गए हों? साभार
बेसिक

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

5

मैं नीचे दिए गए फ़ंक्शन का उपयोग करता हूं ~/.bashrc। यह कुछ ऐसा है जो मुझे अपनी पुरानी लैब में एक सिसडमिन से मिला है, लेकिन मुझे नहीं लगता कि उसने उन्हें लिखा था। बस इन लाइनों को अपने ~/.profileया ~/.bashrc:

pathmunge () {
        if ! echo $PATH | /bin/grep -Eq "(^|:)$1($|:)" ; then
           if [ "$2" = "after" ] ; then
              PATH=$PATH:$1
           else
              PATH=$1:$PATH
           fi
        fi
}

इसके विभिन्न फायदे हैं:

  • नई निर्देशिकाओं को जोड़ना $PATHतुच्छ है pathmunge /foo/bar:;
  • यह डुप्लिकेट प्रविष्टियों से बचा जाता है;
  • आप चुन सकते हैं कि क्या शुरुआत ( pathmunge /foo/barया अंत pathmunge /foo/bar) के बाद एक नई प्रविष्टि जोड़ना है $PATH

आपके शेल की आरंभीकरण फ़ाइल में कुछ इस तरह होगा:

pathmunge /some/dir
pathmunge /another/dir
pathmunge '/another/dir with spaces in it'
pathmunge /yet/another
pathmunge /and/another
pathmunge /end

धन्यवाद। लेकिन मैं @ Starfish का समाधान चुनूंगा क्योंकि उसका स्पॉन नहीं है grep
निकोलो एम।

2
@NiccoloM। कोई समस्या नहीं, स्वीकार करें जो आप कभी भी पसंद करते हैं। स्टारफिश के दृष्टिकोण के साथ सावधान रहें, हालांकि, इसके माध्यम से मनमाना कोड निष्पादित करेगाeval ताकि आप गलत तर्क के साथ इसे चलाने पर कुछ गंभीर नुकसान पहुंचा सकें।
टेराडॉन

ध्यान दें कि बाहरी कमांड के बिना ऐसा करने के लिए फास्ट फ़ंक्शन रेडहैट में मौजूद है grep , को देखने के bugzilla.redhat.com/show_bug.cgi?id=544652#c7
林果皞

4

मैं जोड़ना चाहता हूं, ~ / .bashrc में, मेरी $ PATH के लिए कुछ निर्देशिकाएं।

मैं Cygwin में निम्नलिखित का उपयोग करता हूं। इसे बैश के अन्य संस्करणों में काम करना चाहिए। आप unset PATHअपने वर्तमान पर निर्माण को हटा सकते हैं PATH(यदि आप ऐसा करते हैं तो आपको यह पता लगाना पड़ सकता है कि :विभाजकों को सही तरीके से कैसे जोड़ा जाए )।

ध्यान दें:

  • मैं एक बार एक समारोह में इस कार्यक्षमता था, bashलेकिन एक डिस्क दुर्घटना के बाद इसे खो दिया।

मेरे में .bash_profile:

# Build up the path using the directories in ~/.path_elements
unset PATH
while read line; do 
  PATH="${PATH}$line"; 
done < ~/.path_elements

...

# Add current directory to path
export PATH=".:${PATH}"

इन ~/.path_elements:

/home/DavidPostill/bin:
/usr/local/bin:
/usr/bin:
/c/Windows/system32:
/c/Windows

धन्यवाद। आपके उत्तर ने मुझे सदृश समाधान के लिए प्रेरित किया। (मेरे स्वाद के लिए एक अलग फ़ाइल में पथ संचय करना एक परेशानी है।)
निकोलो एम।

1

मैं इसका उपयोग अपने .bashrc (और भी मेरे .zshrc, के बाद से करता हूं, क्योंकि मैं आमतौर पर bash के बजाय zsh का उपयोग करता हूं)। दी, मुझे निर्देशिकाओं को मैन्युअल रूप से जोड़ने की आवश्यकता है, लेकिन एक फायदा यह है कि जैसे ही मैं इसे अपडेट करता हूं, मैं इसे नए सर्वरों में कॉपी कर सकता हूं और निर्देशिकाओं के साथ बनाए जा रहे नए सर्वर पर पथ के बारे में चिंता न करें।

##
## पथ
##
## हमारे पीएटीएच को केवल निर्देशिकाओं के साथ जोड़ने के बजाय जो हो सकता है
## इस सर्वर के लिए उपयुक्त नहीं है, जो हम जोड़ते हैं उसके बारे में बुद्धिमान होने का प्रयास करें
##
पथ = / usr / स्थानीय / sbin: / usr / स्थानीय / बिन: / usr / sbin: / usr / bin: / sbin: / bin
[-d / cs / sbin] && पथ = / cs / sbin: $ पथ
[-d / सीएस / बिन] && पथ = / सीएस / बिन: $ पाथ
[-d / usr / ucb] && पथ = $ पथ: / usr / ucb
[-d / usr / ccs / bin] && पथ = $ पथ: / usr / ccs / बिन
[-d / usr / स्थानीय / एसएसएल / बिन] && पथ = $ पाथ: / यूएसआर / स्थानीय / एसएसएल / बिन
[-d / usr / krb5 / bin] && पथ = $ पथ: / usr / krb5 / बिन
[-d / usr / krb5 / sbin] && पथ = $ पथ: / usr / krb5 / sbin
[-d / usr / kerberos / sbin] && पथ = $ पथ: / usr / kerberos / sbin
[-d / usr / kerberos / bin] && पथ = $ पथ: / usr / kerberos / बिन
[-d /cs/local/jdk1.5.0/bin] && पथ = $ पथ: /cs/local/jdk1.5.0/bin
[-d /usr/java/jre1.5.0_02/bin] && PATH = $ PATH: /usr/java/jre1.5.0_02/man
[-d /usr/java1.2/bin] && पथ = $ पथ: /us/java1.2/bin
[-d /cs/local/perl5.8.0/bin] && पथ = $ पथ: /cs/local/perl5.8.0/bin
[-d / usr / perl5 / bin] && पथ = $ पथ: / usr / perl5 / बिन
[-d / usr / X11R6 / bin] और& पथ = $ पाथ: / usr / X11R6 / बिन
[-d / etc / X11] && पथ = $ पथ: / etc / X11
[-d / opt / sfw / bin] && पथ = $ पथ: / ऑप्ट / sfw / बिन
[-d / usr / स्थानीय / अपाचे / बिन] && पथ = $ पाथ: / usr / स्थानीय / अपाचे / बिन
[-d / usr / apache / bin] && पथ = $ पथ: / usr / apache / बिन
[-d / cs / admin / bin] && पथ = $ पथ: / cs / व्यवस्थापक / बिन
[-d / usr / ओपनविन / बिन] && पथ = $ पाथ: / यूएसआर / ओपनविन / बिन
[-d / usr / xpg4 / bin] && पथ = $ पथ: / usr / xr4 / बिन
[-d / usr / dt / bin] && पथ = $ पथ: / usr / dt / बिन

मैं अपने MANPATH के लिए भी यही काम करता हूं:

##
## मैनपाट
##
## निर्देशिकाओं के साथ केवल हमारे MANPATH को क्लोब करने के बजाय
## इस सर्वर के लिए उपयुक्त नहीं है, जो हम जोड़ते हैं उसके बारे में बुद्धिमान होने का प्रयास करें
##
MANPATH = / usr / स्थानीय / आदमी
[-d / usr / share / man] && MANPATH = $ MANPATH: / usr / शेयर / आदमी
[-d / usr / स्थानीय / शेयर / आदमी] && MANPATH = $ MANPATH: / usr / स्थानीय / शेयर / आदमी
[-d / usr / man] && MANPATH = $ MANPATH: / usr / आदमी
[-d / cs / man] && MANPATH = $ MANPATH: / cs / आदमी
[-d / usr / krb5 / man] && MANPATH = $ MANPATH: / usr / krb5 / आदमी
[-d / usr / kerberos / man] && MANPATH = $ MANPATH: / usr / kerberos / आदमी
[-d / usr / स्थानीय / ssl / आदमी] && MANPATH = $ MANPATH: / usr / स्थानीय / ssl / आदमी
[-d /cs/local/jdk1.5.0/man] && MANPATH = $ MANPATH: /cs/local/jdk1.5.0/man
[-d /usr/java/jre1.5.0_02/man] && MANPATH = $ MANPATH: /usr/java/jre1.5.0_02/man
[-d /usr/java1.2/man] && MANPATH = $ MANPATH: /usr/java1.2/man
[-d / usr / X11R6 / आदमी] और& MANPATH = $ MANPATH: / usr / X11R6 / आदमी
[-d / usr / स्थानीय / अपाचे / आदमी] && MANPATH = $ MANPATH: / usr / स्थानीय / अपाचे / आदमी
[-d / usr / स्थानीय / mysql / आदमी] && MANPATH = $ MANPATH: / usr / स्थानीय / mysql / आदमी
[-d /cs/local/perl5.8.0/man] && MANPATH = $ MANPATH: /cs/local/perl5.8.0/man
[-d / usr / perl5 / man] && MANPATH = $ MANPATH: / usr / perl5 / आदमी
[-d / usr / स्थानीय / पर्ल / आदमी] && MANPATH = $ MANPATH: / usr / स्थानीय / पर्ल / आदमी
[-d /usr/local/perl5.8.0/man] && MANPATH = $ MANPATH: /usr/local/perl5.8.0/man
[-d / usr / openwin / man] && MANPATH = $ MANPATH: / usr / युविन / मैन

PATH में गैर-विद्यमान निर्देशिकाओं को जोड़ने के डर के बिना एकतरफा वातावरण में सिस्टम को कॉपी कर सकता हूं, जिसके अलावा मैं सिस्टम में कॉपी कर सकता हूं, इस दृष्टिकोण से मुझे उस ऑर्डर को निर्दिष्ट करने की अनुमति देने का भी लाभ है जो मैं चाहता हूं कि निर्देशिकाएं PATH में दिखाई दें। चूंकि प्रत्येक परिभाषा की पहली पंक्ति पूरी तरह से PATH चर को फिर से परिभाषित करती है, मैं अपने .bashrc को अपडेट कर सकता हूं और इसे संपादित करने के बाद अपने शेल को डुप्लिकेट प्रविष्टियों को जोड़े बिना अद्यतन कर सकता हूं (जिसका उपयोग मैं बहुत पहले अनुभव करता था जब मैंने बस शुरू किया था " $ PATH = $ PATH: / new / dir "। यह सुनिश्चित करता है कि मैं जिस क्रम में इच्छा रखता हूं, उसे एक स्वच्छ प्रतिलिपि प्राप्त हो।


1
एक विकल्प का सुझाव देना: d="/usr/share/man" ; [ -d "$d" ] && MANPATH="$MANPATH:${d}"यह एक नया डायर जोड़ना आसान होगा, (केवल एक पंक्ति की प्रतिलिपि बनाएँ और पहले "d = ...." भाग को संपादित करें)। हालाँकि, PATH एक के लिए, मुझे लगता है कि आप अपने PATH में बहुत अधिक dirs के साथ समाप्त होंगे, जो हमेशा अच्छा नहीं होता है (क्या होगा यदि कुछ "foo" कमांड कम ज्ञात पथों में से एक में मौजूद है, और कुछ पूरी तरह से अलग है कि एक नियमित उपयोगकर्ता क्या उम्मीद करेगा?)
ओलिवियर डुलैक

ओपी ने रास्तों को जोड़ने के लिए और अधिक कठिन रास्ता पूछा। यह अब तक की तुलना में अधिक क्रियात्मक और त्रुटि का खतरा है जो वे पहले से ही बचने की कोशिश कर रहे थे।
अंडरस्कोर_ड

-1

एक आसान तरीका है! पढ़ें शैल कार्य और पथ चर पर लिनक्स जर्नल , मार्च 01, 2000 तक स्टीफन Collyer

कार्य मुझे अपने बैश वातावरण में एक नए डेटा प्रकार का उपयोग करने देते हैं - बृहदान्त्र अलग सूची। पथ के अलावा, मैं उनका उपयोग अपने LOCATE_PATH, MANPATH, और अन्य को समायोजित करने के लिए करता हूं, और बैश प्रोग्रामिंग में एक सामान्य डेटाटाइप के रूप में। यहां बताया गया है कि मैंने अपने PATH (कार्यों का उपयोग करके) कैसे सेट किया:

# Add my bin directory to $PATH at the beginning, so it overrides 
addpath -f -p PATH $HOME/bin

# For Raspberry Pi development (add at end)
addpath -b -p PATH ${HOME}/rpi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin

# remove nonexistent directories from PATH
delpath -n -p PATH

# ensure PATH contains unique entries
uniqpath -p PATH

चूंकि लिनक्स जर्नल लिंक को "टूटा हुआ" के रूप में जाना जाता है, इसलिए मैंने http://pastebin.ubuntu.com/13299528/ पर बैश पाथ फ़ंक्शंस को .शर फ़ाइल में डाला है।


3
ये कौन से कार्य हैं? ओपी उनका उपयोग कैसे करता है? संभवतः उन्हें आपके उत्तर में टूटी हुई कड़ी में वर्णित किया गया है, जो ठीक यही है कि हम हमेशा स्वयं को निहित होने के लिए उत्तर चाहते हैं। कृपया अपने उत्तर में वास्तविक कार्यों को संपादित करें और शामिल करें।
टेराडॉन

@terdon: लिंक मेरे लिए काम करता है, मैंने पास्टबिन पर एक .शर फ़ाइल डाल दी है, मैं यहाँ 1K लाइन्स पोस्ट नहीं करूँगा।
वाल्टिनेटर

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