देखो! औद्योगिक-शक्ति 12-लाइन ... तकनीकी रूप से बैश- और zsh- पोर्टेबल शेल फ़ंक्शन जो आपके पसंद के ~/.bashrc
या समर्पित ~/.zshrc
स्टार्टअप स्क्रिप्ट को प्यार करता है :
# void +path.append(str dirname, ...)
#
# Append each passed existing directory to the current user's ${PATH} in a
# safe manner silently ignoring:
#
# * Relative directories (i.e., *NOT* prefixed by the directory separator).
# * Duplicate directories (i.e., already listed in the current ${PATH}).
# * Nonextant directories.
+path.append() {
# For each passed dirname...
local dirname
for dirname; do
# Strip the trailing directory separator if any from this dirname,
# reducing this dirname to the canonical form expected by the
# test for uniqueness performed below.
dirname="${dirname%/}"
# If this dirname is either relative, duplicate, or nonextant, then
# silently ignore this dirname and continue to the next. Note that the
# extancy test is the least performant test and hence deferred.
[[ "${dirname:0:1}" == '/' &&
":${PATH}:" != *":${dirname}:"* &&
-d "${dirname}" ]] || continue
# Else, this is an existing absolute unique dirname. In this case,
# append this dirname to the current ${PATH}.
PATH="${PATH}:${dirname}"
done
# Strip an erroneously leading delimiter from the current ${PATH} if any,
# a common edge case when the initial ${PATH} is the empty string.
PATH="${PATH#:}"
# Export the current ${PATH} to subprocesses. Although system-wide scripts
# already export the ${PATH} by default on most systems, "Bother free is
# the way to be."
export PATH
}
तात्कालिक महिमा के लिए खुद को तैयार करें। फिर, ऐसा करने के बजाय और सबसे अच्छी उम्मीद के लिए:
export PATH=$PATH:~/opt/bin:~/the/black/goat/of/the/woods/with/a/thousand/young
इसके बजाय ऐसा करें और सर्वश्रेष्ठ होने की गारंटी दें, चाहे आप वास्तव में ऐसा चाहते थे या नहीं:
+path.append ~/opt/bin ~/the/black/goat/of/the/woods/with/a/thousand/young
वेरी वेल, डिफाइन "बेस्ट।"
वर्तमान ${PATH}
में सुरक्षित रूप से संलग्न और प्रस्तुत करने का तुच्छ मामला नहीं है जो आमतौर पर इसे बनाया जाता है। जबकि सुविधाजनक और प्रतीत होता है कि समझदार है, इस रूप में वन-लाइनर्स export PATH=$PATH:~/opt/bin
शैतानी जटिलताओं को आमंत्रित करते हैं:
आकस्मिक रूप से सापेक्षिक नाम (जैसे export PATH=$PATH:opt/bin
)। जबकि bash
और zsh
चुपचाप स्वीकार करते हैं और ज्यादातर में रिश्तेदार dirnames उपेक्षा सबसे मामलों, रिश्तेदार dirnames या तो लगाया जाता हैh
या t
(और संभवतः अन्य नापाक अक्षर) दोनों कारण करने के लिए शर्मनाक तरीके से खुद को आला Masaki कोबायाशी के पंगु बना लाभदायक 1962 कृति आत्महत्या :
# Don't try this at home. You will feel great pain.
$ PATH='/usr/local/bin:/usr/bin:/bin' && export PATH=$PATH:harakiri && echo $PATH
/usr/local/bin:/usr/bin:arakiri
$ PATH='/usr/local/bin:/usr/bin:/bin' && export PATH=$PATH:tanuki/yokai && echo $PATH
binanuki/yokai # Congratulations. Your system is now face-up in the gutter.
अकस्मात डुप्लिकेट dirnames।हालांकि ${PATH}
डुप्लीमन डायरनेम काफी हद तक सहज हैं, वे अवांछित, बोझिल, हल्के रूप से अक्षम, अशुद्ध डिबगैबिलिटी, और इस उत्तर की तरह ड्राइव वियर को भी बढ़ावा देते हैं। जबकि नंद शैली के एसएसडी पहनने के लिए ( बेशक ) प्रतिरक्षा हैं, HDDs नहीं हैं। हर प्रयास किए गए कमांड पर अनावश्यक फाइल सिस्टम का उपयोग एक ही टेम्पो में अनावश्यक रूप से पढ़ा जाने वाला हेड वियर है। नेस्टेड उपप्रकारों में नेस्टेड गोले को लागू करते समय डुप्लिकेट विशेष रूप से अप्रभावित होते हैं, जिस बिंदु पर सहज रूप से एक-लाइनर की तरह export PATH=$PATH:~/wat
तेजी से ${PATH}
नरक के सातवें सर्कल में विस्फोट होता है PATH=/usr/local/bin:/usr/bin:/bin:/home/leycec/wat:/home/leycec/wat:/home/leycec/wat:/home/leycec/wat
। केवल Beelzebubba आपकी मदद कर सकता है यदि आप उस पर अतिरिक्त dirnames संलग्न करते हैं। (अपने कीमती बच्चों के साथ ऐसा न करें। )
- अकस्मात गायब दिरनाम। फिर से, जबकि लापता
${PATH}
दिरनामे काफी हद तक सहज हैं, वे आम तौर पर अवांछित, बोझिल, हल्के से अकुशल हैं, डिबगडेबिलिटी को बाधित करते हैं, और ड्राइव पहनने को बढ़ावा देते हैं।
एगो, ऊपर उल्लिखित शेल फ़ंक्शन की तरह अनुकूल स्वचालन। हमें खुद को खुद से बचाना चाहिए।
लेकिन ... क्यों "+ path.append ()"? क्यों नहीं बस append_path ()?
असंबद्धता के लिए (उदाहरण के लिए, वर्तमान में बाहरी आदेशों के साथ ${PATH}
या सिस्टम-वाइड शेल फ़ंक्शन कहीं और परिभाषित), उपयोगकर्ता द्वारा परिभाषित शेल फ़ंक्शन आदर्श उपसर्गों या प्रत्यय द्वारा समर्थित अद्वितीय सब्सट्रिंग के साथ हैं bash
और zsh
अन्यथा मानक कमांड बेसेंम्स के लिए निषिद्ध हैं - जैसे, कहते हैं +
,।
अरे। यह काम करता हैं। मुझे जज मत करो।
लेकिन ... क्यों "+ path.append ()"? क्यों नहीं "+ path.prepend ()"?
क्योंकि वर्तमान के ${PATH}
लिए अपील करना वर्तमान को प्रस्तुत करने की तुलना में अधिक सुरक्षित है ${PATH}
, सभी चीजें समान हैं, जो वे कभी नहीं हैं। उपयोगकर्ता-विशिष्ट आदेशों के साथ सिस्टम-वाइड कमांड को ओवरराइड करना सबसे अच्छा और पागल बनाना सबसे खराब हो सकता है। लिनक्स के तहत, उदाहरण के लिए, डाउनस्ट्रीम एप्लिकेशन आमतौर पर GNU कोरुटिल्स की अपेक्षा करते हैं कस्टम गैर-मानक डेरिवेटिव या विकल्प के बजाय आदेशों वेरिएंट की ।
उस ने कहा, ऐसा करने के लिए बिल्कुल वैध उपयोग के मामले हैं। समतुल्य +path.prepend()
फ़ंक्शन को परिभाषित करना तुच्छ है। सैंस प्रोलिक्स नेबुलोसिटी, उसके और उसके साझा विवेक के लिए:
+path.prepend() {
local dirname
for dirname in "${@}"; do
dirname="${dirname%/}"
[[ "${dirname:0:1}" == '/' &&
":${PATH}:" != *":${dirname}:"* &&
-d "${dirname}" ]] || continue
PATH="${dirname}:${PATH}"
done
PATH="${PATH%:}"
export PATH
}
लेकिन ... गिल्स क्यों नहीं?
गिल्स का स्वीकृत उत्तर कहीं और सामान्य रूप से "शेल एग्नॉस्टिक इम्पोटेंट अपेंडेंट" के रूप में सामान्य रूप से इष्टतम है । के आम मामले में bash
और zsh
साथ कोई अवांछनीय सिमलिंक, हालांकि, प्रदर्शन दंड इतना दुख करने के लिए आवश्यक Gentoo ricer मुझ में। यहां तक कि अवांछनीय सीलिंक की उपस्थिति में, यह बहस का विषय है कि क्या प्रति सब्सक्रिप्शन एक से अधिक हैadd_to_PATH()
तर्क सिम्पीनल डुप्लिकेट के संभावित सम्मिलन के लायक है।
सख्त उपयोग के मामलों की मांग के लिए, यहां तक कि सिमलिंक डुप्लिकेट को भी समाप्त किया जा सकता है, यह- zsh
विशिष्ट संस्करण अक्षम कांटे के बजाय कुशल बिल्डरों के माध्यम से ऐसा करता है:
+path.append() {
local dirname
for dirname in "${@}"; do
dirname="${dirname%/}"
[[ "${dirname:0:1}" == '/' &&
":${PATH}:" != *":${dirname:A}:"* &&
-d "${dirname}" ]] || continue
PATH="${PATH}:${dirname}"
done
PATH="${PATH#:}"
export PATH
}
मूल के *":${dirname:A}:"*
बजाय ध्यान दें *":${dirname}:"*
। सहित अन्य अन्य गोले के तहत :A
एक चमत्कारिक zsh
-दुखद रूप से अनुपस्थित है bash
। बोली के लिए man zshexpn
:
A : a
संशोधक के रूप में फ़ाइल का नाम एक पूर्ण पथ में बदल देता है, और फिर realpath(3)
प्रतीकात्मक लिंक को हल करने के लिए लाइब्रेरी फ़ंक्शन के माध्यम से परिणाम पास करता है । नोट: realpath(3)
जिन सिस्टमों में लाइब्रेरी फंक्शन नहीं है, उन सिम्बॉलिक लिंक्स को हल नहीं किया जाता है, इसलिए वे सिस्टम पर हैं a
और A
समकक्ष हैं।
कोई अन्य प्रश्न नही।
आपका स्वागत है। सुरक्षित गोलाबारी का आनंद लें। अब आप इसके लायक हैं।