Cari tahu skrip apa yang dijalankan oleh bash saat startup

15

Setelah memulai terminal bash, saya perhatikan bahwa variabel PATH berisi entri duplikat. Terminal saya memulai shell login , jadi ~/.bash_profilebersumber, diikuti oleh ~/.profiledan ~/.bashrc. Hanya di ~/.profilesaya membuat entri jalur yang digandakan.

Untuk menjadi bertele-tele, ini adalah urutan di mana file-file yang HARUS dipasok bersumber:

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

Sebelum ada yang menandai ini sebagai duplikat dari "variabel PATH berisi duplikat", terus membaca.

Pada awalnya saya pikir ini ada hubungannya dengan ~/.profilebersumber dua kali, jadi saya meminta file untuk menulis ke file log setiap kali itu bersumber, dan anehnya itu hanya masuk satu entri, yang memberitahu saya bahwa itu hanya bersumber satu kali. Yang lebih mengejutkan adalah fakta bahwa ketika saya mengomentari entri yang ada ~/.profile, entri tersebut masih muncul dalam PATHvariabel. Ini membawa saya ke tiga kesimpulan, salah satunya dengan cepat dikesampingkan:

  1. Bash mengabaikan komentar bash yang valid dan masih mengeksekusi kode yang berkomentar
  2. Ada skrip yang membaca ~/.profiledan mengabaikan kode apa pun yang mencetak output (file log misalnya)
  3. Ada salinan saya ~/.profileyang bersumber di tempat lain

Yang pertama, saya dengan cepat menyimpulkan tidak menjadi masalah karena beberapa pengujian cepat. Opsi kedua dan ketiga adalah tempat saya membutuhkan bantuan.

Bagaimana cara mengumpulkan log skrip yang dijalankan ketika terminal saya mulai? Saya menggunakan echodalam file yang saya periksa untuk mengetahui apakah mereka bersumber oleh bash, tapi saya perlu menemukan metode konklusif yang melacak pelaksanaan sampai pada titik ketika terminal siap bagi saya untuk mulai mengetik ke dalamnya.

Jika hal di atas tidak memungkinkan, maka dapatkah ada yang menyarankan di mana lagi saya dapat melihat untuk melihat skrip yang sedang dijalankan .


Referensi masa depan

Ini skrip yang sekarang saya gunakan untuk menambahkan ke jalur saya:

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
}

Saya menggunakannya seperti ini:

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

Script memeriksa apakah path sudah ada dalam variabel sebelum memprioritaskannya.

Untuk pengguna zsh, Anda dapat menggunakan yang setara ini:

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
}

Edit 28/8/2018

Satu hal lagi yang saya temukan bisa saya lakukan dengan skrip ini adalah juga memperbaiki jalurnya. Jadi pada awal .bashrcfile saya , saya melakukan sesuatu seperti ini:

_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

Terserah Anda apa yang PATHharus dimulai. Periksa PATHdulu untuk memutuskan.

smac89
sumber
Bash hanya membaca dari ~/.profile jika ~/.bash_profiletidak ada ...
jasonwryan
@jasonwryan, saya sumber ~/.profiledan ~/.bashrcdari~/.bash_profile
smac89

Jawaban:

30

Jika sistem Anda memiliki stracemaka Anda dapat membuat daftar file yang dibuka oleh shell, misalnya menggunakan

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

( -liberarti shell login interaktif; gunakan hanya -iuntuk shell non-login interaktif.)

Ini akan menampilkan daftar file yang dibuka atau coba dibuka oleh shell. Di sistem saya, mereka adalah sebagai berikut:

  1. /etc/profile
  2. /etc/profile.d/*(berbagai skrip dalam /etc/profile.d/)
  3. /home/<username>/.bash_profile (ini gagal, saya tidak punya file seperti itu)
  4. /home/<username>/.bash_login (ini gagal, saya tidak punya file seperti itu)
  5. /home/<username>/.profile
  6. /home/<username>/.bashrc
  7. /home/<username>/.bash_history (sejarah baris perintah; ini bukan skrip)
  8. /usr/share/bash-completion/bash_completion
  9. /etc/bash_completion.d/* (berbagai skrip yang menyediakan fungsionalitas pelengkapan otomatis)
  10. /etc/inputrc (mendefinisikan ikatan utama; ini bukan skrip)

Gunakan man straceuntuk informasi lebih lanjut.

AlexP
sumber
Terima kasih atas masukan Anda, tetapi saya pikir ada sesuatu yang salah dengan bash saya. Berjalan echo $0di terminal memberi -bashdaripada yang diharapkan bash. Apakah Anda punya saran lain untuk ini?
smac89
3
@ smac89: Itu normal untuk shell login. Bash berperilaku sebagai shell login ketika karakter pertama $0adalah tanda hubung -, atau ketika dipanggil dengan opsi -l.
AlexP
OK itu sedikit melegakan. Saya telah menjalankan perintah yang Anda berikan dan outputnya terlihat sangat rumit, namun semua file yang ditampilkan tidak mengandung entri yang digandakan. Ini membuat saya berpikir bahwa entri yang digandakan terjadi ketika saya pertama kali masuk ke akun saya, yaitu sesuatu pada awalnya mengambil sumber entri dalam file itu dan itu dilakukan lagi ketika saya membuka terminal? Sebenarnya saya pikir itu mungkin. Ketika saya masuk ke akun saya, entri-entri tersebut bersumber, dan sekali lagi ketika saya membuka terminal prosesnya diulangi. Apakah itu terdengar mungkin?
smac89
Mengapa Anda tidak men-debug cara lama, dengan meletakkan echo PATH=\""$PATH"\"di awal dan akhir .profiledan .bashrc? Dan kenapa tidak Anda melakukan apa yang orang lakukan dan mengatur PATH baik sepenuhnya, atau, jika menambahkan direktori, dijaga: echo ":$PATH:" | grep -q ":/path/to/dir:" || export PATH="$PATH:/path/to/dir"?
AlexP
4
Gunakan sudo bash -c "echo exit|dtruss bash -li|& less|grep '^open'"di macOS. (ganti saja stracedengan dtruss)
Max Coplan