सेवा करने [ -n "$PS1" ]
में क्या प्रयोजन है [ -n "$PS1" ] && source ~/.bash_profile;
? यह रेखा .bashrc
एक डॉटफ़ाइल्स रेपो में शामिल है ।
सेवा करने [ -n "$PS1" ]
में क्या प्रयोजन है [ -n "$PS1" ] && source ~/.bash_profile;
? यह रेखा .bashrc
एक डॉटफ़ाइल्स रेपो में शामिल है ।
जवाबों:
यह जाँच कर रहा है कि शैल संवादात्मक है या नहीं। इस मामले में, केवल ~/.bash_profile
फ़ाइल को सोर्स करना यदि शेल इंटरेक्टिव है।
देखें "क्या यह शेल इंटरएक्टिव है?" बैश मैनुअल में, जो उस विशिष्ट मुहावरे का हवाला देता है। (यह जाँचने की भी सिफारिश करता है कि क्या शेल परीक्षण द्वारा इंटरेक्टिव है कि क्या $-
विशेष चर में i
चरित्र है, जो इस समस्या के लिए एक बेहतर दृष्टिकोण है।)
bash
unsets PS1 जब गैर-सहभागी (आपके पिछले टिप्पणी में टाइपो) एक बग IMO है, PS1, एक पार्टी विशेष के चर नहीं है, यह कोई व्यवसाय यह unsetting है। यह एकमात्र शेल है जो ऐसा करता है (हालांकि गैर-संवादात्मक होने पर भी डिफ़ॉल्ट मान पर yash
सेट PS1
होता है)।
[[ $- = *i* ]] && source ~/.bash_profile
) का सुझाव देता है तो मैं इस उत्तर पर और अधिक पूर्ण विचार करूंगा ।
[ -n "${PS1}" ]
, लेकिन मैंने अभी भी अपने उत्तर को उजागर करने के लिए अद्यतन किया है कि बैश मैनुअल भी यह $-
निर्धारित करने के लिए निरीक्षण / अनुशंसा करता है कि क्या शेल इंटरैक्टिव है, मुझे उम्मीद है कि आप पाएंगे कि उत्तर में सुधार होगा। चीयर्स!
यह परीक्षण का एक व्यापक तरीका है कि क्या खोल इंटरैक्टिव है। खबरदार कि यह केवल बाश में काम करता है, यह अन्य गोले के साथ काम नहीं करता है। तो यह ठीक है (यदि मूर्खतापूर्ण) के लिए .bashrc
, लेकिन यह काम नहीं करेगा .profile
(जो कि श द्वारा पढ़ा जाता है, और बैश केवल श के संभावित कार्यान्वयन में से एक है, और सबसे आम नहीं है)।
एक इंटरैक्टिव शेल डिफ़ॉल्ट प्रॉम्प्ट स्ट्रिंग के लिए शेल चरPS1
सेट करता है । इसलिए यदि शेल संवादात्मक है, PS1
तो सेट किया जाता है (जब तक कि उपयोगकर्ता .bashrc
ने इसे हटा नहीं दिया है, जो अभी तक शीर्ष पर नहीं हुआ है .bashrc
, और आप विचार कर सकते हैं कि यह वैसे भी एक मूर्खतापूर्ण बात है)।
यह बैश में सच है: बैश के गैर-संवादात्मक उदाहरण परेशान होते हैं PS1
जब वे शुरू होते हैं। ध्यान दें कि यह व्यवहार बैश के लिए विशिष्ट है, और यकीनन एक बग (क्यों होता है bash -c '… do stuff with $var…'
जब काम नहीं var
है PS1
?)। लेकिन 4.4 (और जैसा कि मैं लिखता हूं, नवीनतम संस्करण) बैश के सभी संस्करण ऐसा करते हैं।
कई सिस्टम PS1
पर्यावरण को निर्यात करते हैं। यह एक बुरा विचार है, क्योंकि कई अलग-अलग गोले का उपयोग करते हैं PS1
लेकिन एक अलग वाक्यविन्यास के साथ (जैसे बश की त्वरित बचना , ज़ीश के शीघ्र भागने से पूरी तरह से अलग है )। लेकिन यह व्यापक रूप से पर्याप्त है कि व्यवहार में, यह देखते हुए कि PS1
एक विश्वसनीय संकेतक नहीं है कि शेल इंटरैक्टिव है। शेल PS1
पर्यावरण से विरासत में मिला हो सकता है ।
.bashrc
वह फ़ाइल है जो बैश स्टार्टअप में पढ़ता है जब यह इंटरैक्टिव है। एक कम प्रसिद्ध तथ्य यह है कि बैश भी पढ़ता .bashrc
है एक लॉगिन शेल है और बैश के उत्तराधिकारियों का निष्कर्ष है कि यह एक दूरस्थ सत्र है (बैश की जांच करता है कि क्या उसके माता-पिता हैं rshd
या नहीं sshd
)। इस दूसरे मामले में, यह संभावना नहीं है कि PS1
पर्यावरण में सेट किया जाएगा, क्योंकि अभी तक कोई डॉट फ़ाइल नहीं चली है।
हालाँकि, कोड इस जानकारी का उपयोग करने का तरीका उल्टा है।
.bash_profile
उस शेल में चलता है। लेकिन .bash_profile
एक लॉगिन-टाइम स्क्रिप्ट है। यह कुछ कार्यक्रम चला सकता है जो प्रति सत्र केवल एक बार चलाने का इरादा रखते हैं। यह कुछ पर्यावरण चर को ओवरराइड कर सकता है जो उपयोगकर्ता ने उस शेल को चलाने से पहले जानबूझकर एक अलग मूल्य पर सेट किया था। .bash_profile
एक गैर-लॉगिन शेल में चलना विघटनकारी है।.bash_profile
। लेकिन यह ऐसा मामला है जहां लोड .bash_profile
करना उपयोगी हो सकता है, क्योंकि एक गैर-संवादात्मक लॉगिन शेल स्वचालित रूप से लोड नहीं होता है /etc/profile
और ~/.profile
।मुझे लगता है कि लोग ऐसा करने का कारण उन उपयोगकर्ताओं के लिए हैं जो GUI (एक बहुत ही सामान्य मामला) के माध्यम से लॉग इन करते हैं और जिन्होंने .bash_profile
इसके बजाय अपने पर्यावरण चर सेटिंग्स को रखा है .profile
। अधिकांश GUI लॉगिन तंत्र आह्वान करते हैं .profile
लेकिन नहीं .bash_profile
(पढ़ने .bash_profile
के लिए सत्र स्टार्टअप के भाग के रूप में b के बजाय bash चलाने की आवश्यकता होगी)। इस कॉन्फ़िगरेशन के साथ, जब उपयोगकर्ता एक टर्मिनल खोलता है, तो वे अपने पर्यावरण चर प्राप्त करेंगे। हालांकि, उपयोगकर्ता को GUI अनुप्रयोगों में अपने पर्यावरण चर नहीं मिलेंगे, जो भ्रम का एक बहुत ही सामान्य स्रोत है। यहाँ समाधान का उपयोग पर्यावरण चर सेट करने के .profile
बजाय .bash_profile
करना है। के बीच एक पुल जोड़ना .bashrc
और इससे .bash_profile
अधिक समस्याएं पैदा करता है।
परीक्षण का एक सीधा, पोर्टेबल तरीका है कि क्या वर्तमान शेल इंटरेक्टिव है: परीक्षण कि क्या विकल्प -i
सक्षम है।
case $- in
*i*) echo "This shell is interactive";;
*) echo "This shell is not interactive";;
esac
यह केवल पढ़ने के.bashrc
लिए उपयोगी है यदि शेल गैर-संवादात्मक है - अर्थात कोड क्या करता है इसके विपरीत! पढ़ें कि क्या बैश एक (गैर-संवादात्मक) लॉगिन शेल है, और यदि यह एक इंटरैक्टिव शेल है तो इसे न पढ़ें।.profile
.profile
if [[ $- != *i* && -r ~/.profile ]]; then . ~/.profile; fi
[[ -o interactive ]]
(ksh, bash, zsh) या case $- in (*i*) ...; esac
(POSIX)
PS1
अगर अंतःक्रियात्मक रूप से नहीं चलाया जाता है। यह परीक्षण करना काफी आसान है: PS1=cuckoo bash -c '[ -n "${PS1}" ] && echo "PS1=[${PS1}]"'
कुछ भी प्रिंट नहीं करेगा, जबकि आपकी बैश स्टार्टअप फाइलों में सेट PS1=cuckoo bash -i -c '[ -n "${PS1}" ] && echo "PS1=[${PS1}]"'
के मूल्य को प्रिंट करता है $PS1
(यह स्ट्रिंग "कोयल" प्रिंट नहीं करेगा)।
$-
होता है i
एक इंटरैक्टिव खोल के साथ।
[ -n "${PS1}" ]
गलत कॉलिंग बहुत दूर जा रही है, आखिरकार यह केवल तब टूटता है जब कोई PS1 को निर्यात कर रहा है (जो आपके उत्तर में कहता है कि यह एक बुरा विचार है और यहां तक कि इसके कारणों में जाते हैं) और यह प्रभावित नहीं करता है वैसे भी बैश करें (क्योंकि यह PS1 और PS2 को खोल देता है यदि शेल गैर-संवादात्मक है।) शायद "हतोत्साहित" जैसे शब्द का उपयोग करना या दृष्टिकोण की "सीमाओं" के बारे में बात करना बेहतर होता। मुझे नहीं लगता कि यह "गलत" है। अगर कुछ भी गलत है PS1 निर्यात कर रहा है, तो यह सुनिश्चित है! वैसे भी, इस के विवरण में जाने के लिए धन्यवाद।
ऐसा लगता है कि यह अजीब अवधारणा इस तथ्य का परिणाम है कि bash
एक पॉसिक्स शेल क्लोन के रूप में शुरू नहीं हुई थी, लेकिन एक Bourne Shell
क्लोन के रूप में ।
नतीजतन, POSIX इंटरैक्टिव व्यवहार ( $ENV
इंटरेक्टिव गोले के लिए बुलाया जाता है) को बाद में जोड़ा गया है bash
और व्यापक रूप से ज्ञात नहीं है।
एक शेल है जो समान व्यवहार को अनुदान देता है। यह csh
और $prompt
विशिष्ट मूल्य वाले csh अनुदान हैं:
$prompt not set non-interactive shell, test $?prompt.
$prompt set but == "" .cshrc called by the which(1) command.
$prompt set and != "" normal interactive shell.
लेकिन यह न तो बॉर्न शेल पर लागू होता है और न ही पोसिक्स शेल पर।
POSIX शेल के लिए, फ़ाइल में इंटरैक्टिव गोले के लिए कोड डालना एकमात्र तरीका है:
$ENV
इसका एक शेल विशिष्ट नाम है। यह उदा
$HOME/.kshrc for the korn shell
$HOME/.bashrc for bash
$HOME/.mkshrc for mksh
$HOME/.shrc for the POSIX Bourne Shell
अन्य लोगों ने शेल ध्वज का उल्लेख किया -i
, लेकिन यह विश्वसनीय प्रोग्रामिंग के लिए उपयोग करने योग्य नहीं है। POSIX न कि आवश्यकता है set -i
काम करता है, और न ही है कि $-
एक शामिल i
इंटरैक्टिव गोले के लिए। POSIX के लिए केवल यह आवश्यक है कि sh -i
शेल को इंटरेक्टिव मोड में लागू किया जाए।
चूंकि चर $PS1
को पर्यावरण से आयात किया जा सकता है, इसलिए गैर-संवादात्मक मोड में भी इसका मूल्य हो सकता है। तथ्य यह है कि bash
unset
रों PS1
किसी भी गैर-सहभागी खोल में मानक द्वारा दी गई नहीं है और किसी भी अन्य खोल द्वारा नहीं किया।
तो स्वच्छ प्रोग्रामिंग (यहां तक कि bash
) के लिए इंटरैक्टिव गोले के लिए कमांड डालनी है $HOME/.bashrc
।
मैं पहले बात करने जा रहा हूं कि डेबियन क्या है, और ज्यादातर समय उबंटू बैश के लिए भी सेट करता है। और अन्य प्रणालियों पर बाद का स्पर्श।
शेल प्रारंभ फ़ाइलों की सेटिंग में बहुत सारी राय है।
मेरी भी अपनी राय है लेकिन मैं सही सेटिंग्स के मौजूदा उदाहरण दिखाने की कोशिश करूंगा।
मैं डिबुआन का उपयोग करूंगा क्योंकि इसकी फ़ाइलों के उदाहरण ढूंढना काफी आसान है।
और डेबियन का उपयोग किया जाता है, इसलिए सेटिंग्स को अच्छी तरह से परीक्षण किया गया है,
केवल यह पता लगाने के लिए कि शेल इंटरेक्टिव है या नहीं।
डिफ़ॉल्ट /etc/profile
डेबियन में और ubuntu (से / usr / share / आधार फ़ाइलें / प्रोफाइल):
if [ "${PS1-}" ]; then
if [ "${BASH-}" ] && [ "$BASH" != "/bin/sh" ]; then
अगर पढ़ा है: यदि इंटरैक्टिव (PS1 डिफ़ॉल्ट सेट) और यह बैश शेल है (लेकिन डिफ़ॉल्ट के रूप में कार्य नहीं कर रहा है sh
) तो PS1 को किसी विशेष नए (डिफ़ॉल्ट डिफ़ॉल्ट नहीं) में बदल दें।
डिफ़ॉल्ट /etc/bash.bashrc
डेबियन में भी शामिल हैं:
# If not running interactively, don't do anything
[ -z "$PS1" ] && return
यह क्या करता है में बहुत स्पष्ट है: यदि इंटरैक्टिव स्रोत (बाकी) नहीं है।
हालांकि, में /etc/skel/.bashrc
एक उदाहरण है (का उपयोग करते हुए एक इंटरैक्टिव खोल के लिए परीक्षण करने के लिए सही रास्ते से $-
):
# If not running interactively, don't do anything
case $- in
*i*) ;;
*) return;;
esac
यह स्पष्ट रूप से PS1 का एक और एक विकल्प क्यों दिखाना चाहिए।
आपके द्वारा बताई जा रही सेटिंग से बचना चाहिए।
आदेश (सिस्टम सेटिंग से (बैश के लिए) और अधिक विशिष्ट उपयोगकर्ता सेटिंग्स करने के लिए) है /etc/profile
, /etc/bash.bashrc
, ~/.profile
और अंत में ~/.bashrc
। यह सबसे व्यापक प्रभाव डालता है (और अधिक गोले के लिए) /etc/profile
(जिसके पास रूट का स्वामित्व होता है) इसके बाद /etc/bash.bashrc
(जो रूट का भी स्वामित्व होता है) लेकिन केवल बैश को प्रभावित करता है। फिर व्यक्तिगत सेटिंग्स में आते हैं $HOME
, पहला ~/.profile
अधिकांश गोले के लिए है और ~/.bashrc
(लगभग बराबर ~/.bash_profile
), केवल बैश के लिए विशिष्ट है।
इसलिए यह स्रोत के लिए गलत है ~/.bashrc
में ~/.profile
, यह एक विशिष्ट उपयोगकर्ता एक अधिक सामान्य है कि है करने के लिए पार्टी के लिए सेटिंग बदलाव ला रहा है और अधिक गोले को प्रभावित करने वाले । इस तरह से किए जाने पर छोड़कर :
# ~/.profile: executed by the command interpreter for login shells
# if running bash
if [ -n "$BASH_VERSION" ]; then
# include .bashrc if it exists
if [ -f "$HOME/.bashrc" ]; then
. "$HOME/.bashrc"
fi
fi
यह जाँचता है कि बैश चल रहा है और केवल लोड होने पर .bashrc
ही ऐसा है।
यह डेबियन से आने वाला एक अपस्ट्रीम निर्णय है। औचित्य यहाँ समझाया गया है ।
तथ्य यह है, रिवर्स, सोर्सिंग में ~/.profile
में ~/.bash_profile
(या ~/.bashrc
) है केवल फिर से लागू करने के सामान्य नियम है कि पहले से ही एक विशेष उपयोग के मामले के लिए लोड किया जाना चाहिए था, और इसलिए "नहीं है कि बुरा" (मैं नहीं "अच्छा" कह रहा हूँ)। और मैं अच्छा नहीं कह रहा हूं क्योंकि इससे फाइलों की सोर्सिंग लूप हो सकती है। जैसे जब एक उप-निर्देशिका एक माता-पिता को लोड करती है, तो वह एक निर्देशिका लूप होती है।
और इस क्रॉस सोर्सिंग में है कि इंटरेक्टिव शेल के लिए चेक समझ में आता है। केवल जब एक शेल इंटरेक्टिव होता है ~/.bashrc
, तो लोड किया जाता है, लेकिन यह बदले में लोड हो सकता है ~/.profile
(या अन्य तरीके से) और इस मामले में है कि एक इंटरेक्टिव शेल के लिए जाँच का उपयोग किया जा सकता है।
( export PS1='abc$ '; bash -c 'echo "[$PS1]"' )
, जो केवल प्रिंट करता है[]
। ऐसा लगता है कि zsh ऐसा नहीं करता है, कम से कम एक प्रयोग से ... किसी भी मामले में, यह जाँचने का इरादा है[ -n "$PS1" ]
कि शेल संवादात्मक है या नहीं।