Memilih antara .bashrc, .profile, .bash_profile, dll [duplikat]

197

Pertanyaan ini sudah ada jawabannya di sini:

Ini memalukan, tapi setelah bertahun-tahun menggunakan sistem POSIX penuh waktu, saya masih memiliki waktu yang sulit mencari tahu apakah kustomisasi shell harus pergi di .bashrc, .profile, atau di tempat lain. Belum lagi beberapa file konfigurasi OS khusus seperti .pam_environment.

Ya, saya tahu cara memecahkan dokumentasi dan belajar kapan setiap file dimuat atau tidak. Yang saya ingin tahu adalah apakah ada orang yang telah menyusun panduan komprehensif untuk bagaimana memutuskan file mana yang akan dikustomisasi.

Avdi
sumber
6
pertanyaan ini tidak boleh ditandai sebagai duplikat alasannya adalah. profil tidak tersedia di pertanyaan yang ditambahkan.
Premraj

Jawaban:

222

TL; DR:

  • ~/.bash_profileharus super sederhana dan hanya memuat .profiledan .bashrc(dalam urutan itu)

  • ~/.profilememiliki barang-barang TIDAK secara spesifik terkait dengan bash, seperti variabel lingkungan ( PATHdan teman)

  • ~/.bashrcmemiliki apa pun yang Anda inginkan di baris perintah interaktif. Command prompt, EDITORvariabel, alias bash untuk saya gunakan

Beberapa catatan lain:

  • Apa pun yang harus tersedia untuk aplikasi grafis ATAU untuk sh (atau bash dipanggil sebagai sh) HARUS masuk~/.profile

  • ~/.bashrc tidak boleh mengeluarkan apapun

  • Apa pun yang seharusnya tersedia hanya untuk masuk shell harus masuk ~/.profile

  • Pastikan itu ~/.bash_logintidak ada.

Dan Rabinowitz
sumber
3
+1, ini memungkinkan ~/.profilepengaturan lingkungan yang tepat untuk layanan seperti GDM / LightDM / LXDM yang secara eksplisit menjalankan / bin / sh.
grawity
12
.bashrcKeluaran saya cukup banyak, bisakah Anda mengomentari itu? Secara khusus, di mana saya harus meletakkan output ucapan?
Calimo
14
@ Calimo: Buatlah hanya menghasilkan barang dalam mode interaktif. Anda dapat menguji untuk itu menggunakan [[ $- == *i* ]], yaitu, mencari 'i' dalam $-variabel khusus . Tentu saja, itu hanya penting di tempat pertama pada sistem di mana bash dikompilasi untuk membaca .bashrcdalam mode non-interaktif. (Yaitu, Debian tetapi tidak Arch.) Tapi itu sering menjadi penyebab pesan kesalahan misterius ketika mencoba menghubungkan menggunakan sftpatau scpatau alat serupa.
grawity
4
Sekarang saya harus tahu - mengapa .bash_login tidak ada? Apa fungsinya?
tedder42
11
@ tedder42: Kerjanya sama dengan .bash_profiledan .profile. Tapi bash hanya membaca yang pertama dari tiga. Artinya, jika Anda memiliki .bash_login, maka keduanya .profiledan .bash_profileakan diabaikan secara misterius.
grawity
54

Selama beberapa tahun terakhir, saya punya banyak waktu untuk dihabiskan, jadi saya telah meneliti ini lebih dari 10 menit. Saya tidak tahu apakah ini tata letak terbaik, itu hanya salah satu yang bekerja dengan benar di hampir semua kasus.

Persyaratan:

  • ~/.profile harus kompatibel dengan sembarang / bin / sh - ini termasuk bash, dash, ksh, apa pun yang mungkin dipilih distro untuk digunakan.

  • Variabel lingkungan harus dimasukkan ke dalam file yang dibaca oleh kedua login konsol (yaitu shell 'login') dan login grafis (yaitu manajer tampilan seperti GDM, LightDM, atau LXDM).

  • Ada sedikit gunanya memiliki keduanya ~/.profile dan ~/.bash_profile. Jika yang terakhir hilang, bash akan dengan senang hati menggunakan yang pertama, dan setiap baris spesifik bash dapat dijaga dengan cek untuk $BASHatau $BASH_VERSION.

  • Pemisahan antara *profiledan *rcadalah bahwa yang pertama digunakan untuk shell 'login', dan yang terakhir setiap kali Anda membuka jendela terminal. Namun, bash dalam mode 'login' tidak sumber ~/.bashrc, oleh karena itu ~/.profileperlu melakukannya secara manual.

The sederhana konfigurasi akan:

  • Memiliki ~/.profileyang mengatur semua variabel lingkungan (kecuali yang spesifik-bash), mungkin mencetak satu atau dua baris, lalu sumber ~/.bashrcjika dijalankan oleh bash, tetap menggunakan sintaks yang kompatibel dengan sh sebaliknya.

    ekspor TZ = "Eropa / Paris"
    export EDITOR = "vim"
    if ["$ BASH"]; kemudian
        . ~ / .bashrc
    fi
    uptime
    
  • Miliki ~/.bashrcyang melakukan pengaturan khusus shell, dijaga dengan pemeriksaan untuk mode interaktif untuk menghindari kerusakan hal-hal seperti sftpdi Debian (di mana bash dikompilasi dengan opsi untuk memuat ~/.bashrcbahkan untuk shell non-interaktif):

    [[$ - == * i *]] || kembali 0
    
    PS1 = '\ h \ w \ $'
    
    start () {sudo service "$ 1" start; }
    

Namun, ada juga masalah yang ssh <host> lsdilewati perintah non-interaktif tertentu (misalnya ) ~/.profile, tetapi variabel lingkungan akan sangat berguna bagi mereka.

  • Distribusi tertentu (mis. Debian) mengompilasi bash mereka dengan opsi untuk sumber ~/.bashrcuntuk login non-interaktif tersebut. Dalam hal ini, saya merasa berguna untuk memindahkan semua variabel lingkungan ( export ...baris) ke file yang terpisah ~/.environ,, dan untuk mengambilnya dari keduanya .profile dan .bashrc, dengan penjaga untuk menghindari melakukannya dua kali:

    jika! ["$ PREFIX"]; kemudian    # atau $ EDITOR, atau $ TZ, atau ... 
        . ~ / .environ            # pada umumnya variabel apa saja yang diatur oleh .environ itu sendiri
    fi
    
  • Sayangnya, untuk distribusi lain (misalnya Arch), saya belum menemukan solusi yang sangat bagus. Salah satu kemungkinan adalah dengan menggunakan modul PAM (diaktifkan secara default) pam_env, dengan memasukkan yang berikut ini ~/.pam_environment:

    BASH_ENV =. / .Viron         # bukan kesalahan ketik; itu perlu jalan, tapi ~ tidak akan berhasil
    

    Kemudian, tentu saja, memperbarui ~/.environke unset BASH_ENV.


Kesimpulan? Kerang itu menyakitkan. Variabel lingkungan itu menyebalkan. Pilihan waktu kompilasi distribusi khusus adalah rasa sakit yang luar biasa di pantat.

grawity
sumber
2
+1 untuk paragraf terakhir, tapi saya lebih suka sumber .profiledan .bashrcdari .bash_profiledan menjaga .profilekebersihan.
nyuszika7h
@ nyuszika7h: My .profile bersih , terima kasih.
grawity
1
Perhatikan komentar ulang setiap kali Anda membuka jendela adalah sebaliknya untuk OSX
Mark
1
"Ada sedikit gunanya memiliki keduanya ~/.profiledan ~/.bash_profile": Saya tidak setuju. Lihat jawaban Dan untuk alasannya.
rubenvb
@rubenvb Bisakah Anda mengutip bagian yang relevan? Saya pikir tidak apa-apa untuk hanya memiliki .profiledan menjaga bashbagian-bagian khusus dengan persyaratan.
Kelvin
36

Lihat posting blog yang luar biasa ini oleh ShreevatsaR . Berikut adalah ekstrak, tetapi pergi ke posting blog, itu termasuk penjelasan untuk istilah-istilah seperti "shell login", diagram alur, dan tabel serupa untuk Zsh.

Untuk Bash, mereka bekerja sebagai berikut. Baca kolom yang sesuai. Menjalankan A, lalu B, lalu C, dll. B1, B2, B3 berarti hanya mengeksekusi yang pertama dari file-file yang ditemukan.

+----------------+-----------+-----------+------+
|                |Interactive|Interactive|Script|
|                |login      |non-login  |      |
+----------------+-----------+-----------+------+
|/etc/profile    |   A       |           |      |
+----------------+-----------+-----------+------+
|/etc/bash.bashrc|           |    A      |      |
+----------------+-----------+-----------+------+
|~/.bashrc       |           |    B      |      |
+----------------+-----------+-----------+------+
|~/.bash_profile |   B1      |           |      |
+----------------+-----------+-----------+------+
|~/.bash_login   |   B2      |           |      |
+----------------+-----------+-----------+------+
|~/.profile      |   B3      |           |      |
+----------------+-----------+-----------+------+
|BASH_ENV        |           |           |  A   |
+----------------+-----------+-----------+------+
|                |           |           |      |
+----------------+-----------+-----------+------+
|                |           |           |      |
+----------------+-----------+-----------+------+
|~/.bash_logout  |    C      |           |      |
+----------------+-----------+-----------+------+
Flimm
sumber
Ini bagus. Penting untuk dicatat bahwa biasanya /etc/profilepanggilan /etc/bash.bashrc, dan ~/.profilepanggilan ~.bashrc. Begitu efektif, /etc/bash.bashrcdan ~/.bashrcsedang dieksekusi untuk Login Interaktif juga.
wisbucky
Perhatikan bahwa beberapa distribusi tampaknya menimpa skema ini (dengan konsekuensi aneh) - lihat misalnya laporan bug saya ke opensuse di sini: bugzilla.opensuse.org/show_bug.cgi?id=1078124
Christian Herenz
Btw. setidaknya dengan bash, tidak ada file yang dieksekusi ketika bash dipanggil melalui/bin/sh
JepZ
@JepZ Anda benar, itulah yang dijelaskan kolom ketiga "Script".
Flimm
1
@Flimm Nah, kolom 'Skrip' menggambarkan apa yang terjadi ketika Anda memulai skrip non-interaktif melalui bash (misalnya / bin / bash). Namun, jika Anda memulai skrip melalui sh (dan / bin / sh adalah symlink ke / bin / bash) tidak satu pun di atas dijalankan (bahkan tidak BASH_ENV). Paragraf terkait dari halaman bash man dapat ditemukan dengan mencari If bash is invoked with the name sh.
JepZ
21

Saya menawarkan pedoman "komprehensif":

  • Buat .bash_profiledan .profilemuat .bashrcjika ada, menggunakan mis [ -r $HOME/.bashrc ] && source $HOME/.bashrc
  • Masukkan semua yang lain .bashrc.
  • Berhenti mengkhawatirkan.
  • Setiap empat tahun sekali, habiskan sepuluh menit untuk meneliti pertanyaan ini sebelum menyerah dan kembali ke "tidak khawatir".

EDIT: Menambahkan kutipan menakut-nakuti ke "komprehensif" kalau-kalau ada orang yang tergoda untuk percaya. ;)

Ikan Mekanis
sumber
3
Memiliki keduanya .bash_profiledan .profilesedikit berlebihan; Anda hanya membutuhkan yang terakhir. Anda perlu membuatnya / bin / sh-proof, meskipun if [ "$BASH" ] && [ -r ~/.bashrc ]; then . ~/.bashrc; fi:, karena ada program (yaitu gdm / lightdm) yang secara manual sumber file dari skrip / bin / sh. Ini juga berarti bahwa lingkungan yang disimpan .bashrctidak akan efektif. Harus -1, karena pedoman "komprehensif" Anda tidak akan bekerja pada banyak sistem, karena saya telah menemukan jalan yang sulit beberapa kali.
grawity
Tidak masalah, saya dengan senang hati akan membayar -1 untuk jawaban yang tidak hanya "komprehensif", dan Anda pasti mendapatkan gelar itu.
Ikan Mekanis
0

Saya menyerah untuk mencoba mencari yang ini dan membuat satu skrip ( ~/.shell-setup) yang saya sumber dari yang lain.

Pendekatan ini ~/.shell-setupharus memiliki dua fitur:

  1. Hanya jalankan sekali, bahkan saat bersumber berulang (gunakan Sertakan penjaga )
  2. Jangan menghasilkan output yang tidak diinginkan (deteksi ketika output ok)

# 1 cukup standar, meskipun mungkin tidak banyak digunakan dalam skrip shell.

# 2 lebih rumit. Inilah yang saya gunakan dalam bash:

if [ "" == "$BASH_EXECUTION_STRING" -a "" == "$DESKTOP_SESSION" ]; then
    echo "Hello user!" # ... etc
fi

Sayangnya saya tidak ingat bagaimana saya menemukan itu, atau mengapa mendeteksi shell interaktif tidak cukup.

ShadSterling
sumber
-2

Masukkan semuanya ke dalam .bashrcdan kemudian sumber .bashrcdari.profile

Dari halaman bash man (pada OS X 10.9):

Ketika shell interaktif yang bukan shell login dimulai, bash membaca dan mengeksekusi perintah dari ~ / .bashrc, jika file itu ada. Ini dapat dihambat dengan menggunakan opsi --norc. Opsi file --rcfile akan memaksa bash untuk membaca dan menjalankan perintah dari file daripada ~ / .bashrc

Teks di atas adalah mengapa semuanya dimasukkan .bashrc. Namun, ada perilaku yang sedikit berbeda ketika Anda berurusan dengan shell login. Sekali lagi, mengutip dari halaman manual:

Ketika bash dipanggil sebagai shell login interaktif, atau sebagai shell non-interaktif dengan opsi --login, ia pertama kali membaca dan mengeksekusi perintah dari file / etc / profile, jika file itu ada. Setelah membaca file itu, ia mencari ~ / .bash_profile, ~ / .bash_login, dan ~ / .profile, dalam urutan itu, dan membaca serta mengeksekusi perintah dari yang pertama yang ada dan dapat dibaca. Opsi --noprofile dapat digunakan ketika shell mulai menghambat perilaku ini.

.profiledibaca untuk shell login, tetapi .bashrctidak. Menggandakan semua hal itu .bashrcadalah bad ™ sehingga kita perlu sumbernya .profileagar perilaku tetap konsisten.

Namun, Anda tidak ingin sumber .bashrcdari .profiletanpa syarat. Silakan lihat komentar dan jawaban lain untuk detail tambahan.

mattr-
sumber
4
-1, JANGAN sumber .bashrcdari .profile. Lihat jawaban @ DanRabinowitz.
nyuszika7h
Setidaknya tidak tanpa syarat.
nyuszika7h
[ -n "$BASH" -a -f ~/.bashrc ] && . ~/.bashrcakan menjadi oneliner yang manis untuk .profile.
John WH Smith
@ nyuszika7h, Kenapa tidak? Semua orang sepertinya menyarankan untuk melakukannya.
Pacerier