पता करें कि स्टार्टअप पर बैश करके क्या स्क्रिप्ट चल रही हैं


15

बैश टर्मिनल शुरू करने के बाद, मैंने देखा कि पैठ चर में डुप्लिकेट प्रविष्टियाँ हैं। मेरा टर्मिनल एक लॉगिन शेल शुरू करता है , इसलिए ~/.bash_profileइसे सॉर्ट किया जाता है, उसके बाद ~/.profileऔर ~/.bashrc। केवल ~/.profileमैं उन रास्तों की प्रविष्टियाँ बनाता हूँ जो डुप्लिकेट हैं।

पांडित्यपूर्ण होने के लिए, यह वह क्रम है जिसमें उन फाइलों को खंगाला जा सकता है जिन्हें खट्टा किया जा रहा है:

Sourced /etc/profile
Sourced /etc/bash.bashrc
Sourced .bash_profile
Sourced .profile
Sourced .bashrc

इससे पहले कि कोई भी इसे "पाथ चर के डुप्लिकेट में डुप्लिकेट" के रूप में चिह्नित करता है, पढ़ते रहें।

पहले तो मुझे लगा कि ~/.profileदो बार खट्टा होने के साथ ऐसा करना है , इसलिए जब भी इसे खट्टा किया जाता, तो मुझे एक लॉग फाइल पर लिखना पड़ता, और आश्चर्यजनक रूप से इसने केवल एक प्रविष्टि दर्ज की, जो मुझे बताती है कि यह केवल एक बार ही खट्टी थी। इससे भी अधिक आश्चर्य की बात यह है कि जब मैं उन प्रविष्टियों की टिप्पणी करता हूं जो अंदर थीं ~/.profile, तो प्रविष्टियां अभी भी PATHचर में दिखाई देती हैं। इसने मुझे तीन निष्कर्षों तक पहुँचाया है, जिनमें से एक को जल्दी ही समाप्त कर दिया गया था:

  1. बैश मान्य बैश टिप्पणियों को अनदेखा करता है और अभी भी टिप्पणी कोड निष्पादित करता है
  2. एक स्क्रिप्ट है जो ~/.profileआउटपुट को प्रिंट करने वाले किसी भी कोड को पढ़ता है और अनदेखा करता है (उदाहरण के लिए लॉग फ़ाइल)
  3. मेरी एक और प्रति है ~/.profileजिसे कहीं और खट्टा किया जा रहा है

पहले एक, मैंने जल्दी से निष्कर्ष निकाला कि कुछ त्वरित परीक्षण के कारण मामला नहीं होगा। दूसरा और तीसरा विकल्प वह है जहाँ मुझे मदद की ज़रूरत है।

मैं उन स्क्रिप्ट्स का एक लॉग कैसे इकट्ठा करूं जो मेरे टर्मिनल के शुरू होने पर क्रियान्वित की जाती हैं? मैंने echoउन फ़ाइलों का उपयोग किया जिन्हें मैंने यह जानने के लिए चेक किया था कि क्या वे बैश द्वारा खट्टे हैं, लेकिन मुझे एक निर्णायक विधि खोजने की आवश्यकता है जो तब बिंदु को निष्पादित करती है जब टर्मिनल मेरे लिए तैयार होता है कि मैं उसमें टाइप करना शुरू कर दें।

यदि उपरोक्त संभव नहीं है, तो क्या कोई सुझाव दे सकता है कि मैं कहां देख सकता हूं कि कौन सी स्क्रिप्ट चल रही हैं


भविष्य के सन्दर्भ

यह वह पटकथा है जिसे अब मैं अपने पथ में जोड़ने के लिए उपयोग करता हूं:

function add_to_path() {
    for path in ${2//:/ }; do
        if ! [[ "${!1}" =~ "${path%/}" ]]; then # ignore last /
            new_path="$path:${!1#:}"
            export "$1"="${new_path%:}" # remove trailing :
        fi
    done
}

मैं इसे इस तरह से उपयोग करता हूं:

add_to_path 'PATH' "/some/path/bin"

स्क्रिप्ट जाँचता है कि क्या पथ पहले से ही चर में मौजूद है।

Zsh उपयोगकर्ताओं के लिए, आप इस समकक्ष का उपयोग कर सकते हैं:

function add_to_path() {
    for p in ${(s.:.)2}; do
        if [[ ! "${(P)1}" =~ "${p%/}" ]]; then
            new_path="$p:${(P)1#:}"
            export "$1"="${new_path%:}"
        fi
    done
}

संपादित करें 28/8/2018

एक और बात जो मुझे लगी कि मैं इस पटकथा के साथ कर सकता हूं वह भी मार्ग को ठीक करना है। इसलिए अपनी .bashrcफ़ाइल की शुरुआत में , मैं कुछ इस तरह से करता हूं:

_temp_path="$PATH"
PATH='/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin'
add_to_path 'PATH' "$_temp_path"
unset _temp_path

यह आप पर निर्भर है कि PATHशुरुआत किससे होनी चाहिए। PATHतय करने के लिए पहले जांच करें ।


बैश केवल तभी से पढ़ता है ~/.profile जब ~/.bash_profileवह मौजूद नहीं होता है ...
जसोनव्रीयन

@ मैंजोनरीवन, मैं स्रोत ~/.profileऔर ~/.bashrcसे~/.bash_profile
smac89

जवाबों:


30

यदि आपके सिस्टम में है straceतो आप शेल द्वारा खोली गई फाइलों को सूचीबद्ध कर सकते हैं, उदाहरण के लिए

echo exit | strace bash -li |& grep '^open'

( -liमतलब लॉगिन शैल इंटरेक्टिव। केवल -iइंटरएक्टिव नॉन-लॉगिन शेल के लिए उपयोग करें ।)

यह उन फ़ाइलों की एक सूची दिखाएगा जिन्हें खोल दिया गया था या खोलने की कोशिश की गई थी। मेरे सिस्टम पर, वे इस प्रकार हैं:

  1. /etc/profile
  2. /etc/profile.d/*(विभिन्न लिपियों में /etc/profile.d/)
  3. /home/<username>/.bash_profile (यह विफल रहता है, मेरे पास ऐसी कोई फ़ाइल नहीं है)
  4. /home/<username>/.bash_login (यह विफल रहता है, मेरे पास ऐसी कोई फ़ाइल नहीं है)
  5. /home/<username>/.profile
  6. /home/<username>/.bashrc
  7. /home/<username>/.bash_history (कमांड लाइनों का इतिहास; यह एक स्क्रिप्ट नहीं है)
  8. /usr/share/bash-completion/bash_completion
  9. /etc/bash_completion.d/* (विभिन्न स्क्रिप्ट जो स्वत: पूर्णता कार्यक्षमता प्रदान करती हैं)
  10. /etc/inputrc (कुंजी बाइंडिंग को परिभाषित करता है; यह एक स्क्रिप्ट नहीं है)

man straceअधिक जानकारी के लिए उपयोग करें ।


आपके इनपुट के लिए धन्यवाद, लेकिन मुझे लगता है कि मेरे बैश में कुछ गड़बड़ है। echo $0टर्मिनल में दौड़ना -bashउम्मीद के बजाय देता है bash। क्या आपके पास इसके लिए कोई अन्य सुझाव है?
smac89

3
@ smac89: यह एक लॉगिन शेल के लिए सामान्य है। बैश एक लॉगिन शेल के रूप में व्यवहार करता है जब 1 वर्ण $0एक डैश होता है -, या जब विकल्प के साथ आह्वान किया जाता है -l
अलेक्सप

ठीक है कि थोड़ी राहत है। मैंने आपके द्वारा दी गई कमांड को चलाया है और आउटपुट वास्तव में जटिल दिखता है, लेकिन फिर भी दिखाई गई सभी फाइलों में डुप्लिकेट की गई प्रविष्टियाँ नहीं हैं। यह सोचने के लिए मुझे प्रेरित कर रहा है कि डुप्लिकेट की गई प्रविष्टियाँ तब होती हैं जब मैं पहली बार अपने खाते में प्रवेश करता हूं, यानी कुछ शुरू में उस फ़ाइल में प्रविष्टियों को सोर्स कर रहा होता है और यह तब होता है जब मैं टर्मिनल खोलता हूं? वास्तव में मुझे लगता है कि यह हो सकता है। जब मैं अपने खाते में प्रवेश करता हूं, तो प्रविष्टियां दर्ज की जाती हैं, और जब मैं टर्मिनल खोलता हूं तो प्रक्रिया दोहराई जाती है। क्या यह संभव है?
smac89

आप पुराने जमाने के तरीके को डिबग क्यों नहीं करते हैं, echo PATH=\""$PATH"\"शुरुआत और अंत में डालकर .profileऔर .bashrc? और आप ऐसा क्यों नहीं करते हैं जो हर कोई करता है और पैथ को पूरी तरह से सेट करता है, या, यदि कोई निर्देशिका जोड़ रहा है, तो संरक्षित है echo ":$PATH:" | grep -q ":/path/to/dir:" || export PATH="$PATH:/path/to/dir":?
एलेक्स

4
sudo bash -c "echo exit|dtruss bash -li|& less|grep '^open'"MacOS पर उपयोग करें । (बस के straceसाथ बदलें dtruss)
मैक्स कोपलान
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.