Başlangıçta bash tarafından hangi komut dosyalarının çalıştırıldığını öğrenin


15

Bir bash terminalini başlattıktan sonra, PATH değişkeninin yinelenen girişler içerdiğini fark ettim. Terminalim bir giriş kabuğu başlatır , bu ~/.bash_profilenedenle kaynaklanır ve ardından ~/.profileve gelir ~/.bashrc. Yalnızca ~/.profileçoğaltılan yol girişlerini oluşturuyorum.

Bilgiçlikçi olmak için, kaynak olması gereken dosyaların kaynağı şu şekildedir:

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

Herhangi biri bunu "PATH değişkeni yinelenen içeriyor" ifadesi olarak işaretlemeden önce okumaya devam edin.

İlk başta bu ~/.profileiki kez kaynak ile ilgili olduğunu düşündüm , bu yüzden her zaman bir günlük dosyasına dosya yazmak vardı ve şaşırtıcı bir şekilde, sadece bir kez kaynak olduğunu söyleyen sadece bir giriş günlüğe vardı. Daha da şaşırtıcı olan şey, içerideki ~/.profilegirişleri yorumladığımda, girişlerin hala PATHdeğişkente görünmesidir . Bu beni üç sonuca götürdü, bunlardan biri hızla reddedildi:

  1. Bash geçerli bash yorumlarını yok sayar ve hala yorumlanan kodu yürütür
  2. ~/.profileBir çıktıyı (örneğin günlük dosyası) yazdıran kodu okuyan ve yok sayan bir komut dosyası vardır.
  3. Başka bir ~/.profileyerden temin edeceğim başka bir kopyası var

Birincisi, bazı hızlı testler nedeniyle hızlı bir şekilde durumun olmadığı sonucuna vardım. İkinci ve üçüncü seçenekler yardıma ihtiyacım olan yerler.

Terminalim başladığında yürütülen komut dosyalarının kaydını nasıl toplayabilirim? echoBash tarafından kaynaklanıp kaynaklanmadığını öğrenmek için kontrol ettiğim dosyalarda kullandım , ancak terminal yazmaya başlamam için hazır olduğunda uygulamayı yürüten kesin bir yöntem bulmam gerekiyor.

Yukarıdakiler mümkün değilse, başka hangi komut dosyalarının çalıştırıldığını görmek için başka nereye bakabileceğimi önerebilir .


Gelecek referans

Bu, şimdi yoluma eklemek için kullandığım komut dosyası:

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
}

Ben böyle kullanın:

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

Komut dosyası, yolu eklemeden önce değişkente zaten var olup olmadığını kontrol eder.

Zsh kullanıcıları için bu eşdeğerini kullanabilirsiniz:

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
}

Düzenle 28/8/2018

Bu komut dosyasıyla yapabileceğimi bulduğum bir şey daha yolu düzeltmektir. Yani dosyamın başında, .bashrcböyle bir şey yapıyorum:

_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

Ne ile PATHbaşlamalı size kalmış . Karar PATHvermek için önce inceleyin .


Dan Bash sadece okur ~/.profile eğer ~/.bash_profileyoksa ...
jasonwryan

@jasonwryan, kaynak ~/.profileve ~/.bashrcgelen~/.bash_profile
smac89

Yanıtlar:


30

Sisteminiz varsa strace, kabuk tarafından açılan dosyaları listeleyebilirsiniz, örneğin

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

( -ligiriş kabuğu etkileşimli anlamına gelir; yalnızca -ietkileşimli giriş yapmayan kabuk için kullanın.)

Bu, kabuğun açtığı veya açmaya çalıştığı dosyaların bir listesini gösterir. Sistemimde bunlar aşağıdaki gibidir:

  1. /etc/profile
  2. /etc/profile.d/*(çeşitli komut dosyaları /etc/profile.d/)
  3. /home/<username>/.bash_profile (bu başarısız, böyle bir dosyam yok)
  4. /home/<username>/.bash_login (bu başarısız, böyle bir dosyam yok)
  5. /home/<username>/.profile
  6. /home/<username>/.bashrc
  7. /home/<username>/.bash_history (komut satırlarının geçmişi; bu bir komut dosyası değildir)
  8. /usr/share/bash-completion/bash_completion
  9. /etc/bash_completion.d/* (otomatik tamamlama işlevi sağlayan çeşitli komut dosyaları)
  10. /etc/inputrc (anahtar bağlamaları tanımlar; bu bir komut dosyası değildir)

man straceDaha fazla bilgi için kullanın .


Girişiniz için teşekkürler, ama bash'ımla ilgili ciddi bir sorun olduğunu düşünüyorum. echo $0Terminalde koşmak -bashbeklenenden daha fazlasını verir bash. Bunun için başka önerileriniz var mı?
smac89

3
@ smac89: Bir giriş kabuğu için bu normal. Bash, karakterinin ilk karakteri $0tire işareti -olduğunda veya seçenekle çağrıldığında bir giriş kabuğu gibi davranır -l.
AlexP

Tamam, bu biraz rahatlama. Verdiğiniz komutu çalıştırdım ve çıktı gerçekten karmaşık görünüyor, ancak yine de gösterilen tüm dosyalar yinelenen girişleri içermiyor. Bu, hesabımda ilk kez oturum açtığımda yinelenen girişlerin olduğunu düşündürüyor, yani bir şey başlangıçta bu dosyadaki girişleri kaynaklanıyor ve terminali açtığımda tekrar mı yapılıyor? Aslında bence bu olabilir. Hesabıma giriş yaptığımda girişler kaynaklanıyor ve terminali açtığımda işlem tekrarlanıyor. Bu mümkün mü?
smac89

Neden koyarak, eski moda şekilde hata ayıklama yok echo PATH=\""$PATH"\"başında ve sonunda .profileve .bashrc? Ve neden korunan, bir dizin ekleyerek eğer herkes yapar ve ya tamamen PATH set, ya da ne yapmıyoruz: echo ":$PATH:" | grep -q ":/path/to/dir:" || export PATH="$PATH:/path/to/dir"?
AlexP

4
sudo bash -c "echo exit|dtruss bash -li|& less|grep '^open'"MacOS'ta kullanın . (sadece değiştirmek straceile dtruss)
Max COPLAN
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.