Perbedaan antara .bashrc dan .bash_profile

449

Apa perbedaan antara .bashrcdan .bash_profiledan mana yang harus saya gunakan?

cfischer
sumber
2
Lihat juga pertanyaan serupa ini di ubuntu.stackexchange.com/questions/1528/bashrc-or-bash-profile
Stefan Lasiewski
Jika Anda ingin penjelasan yang lebih lengkap yang juga melibatkan .profile, lihat pertanyaan ini: superuser.com/questions/789448/…
Flimm
Jawaban ini juga mencakup beberapa aspek stackoverflow.com/questions/415403/…
Sergey Voronezhskiy

Jawaban:

517

Secara tradisional, ketika Anda masuk ke sistem Unix, sistem akan memulai satu program untuk Anda. Program itu adalah shell, yaitu program yang dirancang untuk memulai program lain. Ini adalah shell baris perintah: Anda memulai program lain dengan mengetikkan namanya. Shell default, shell Bourne, membaca perintah ~/.profileketika dipanggil sebagai shell login.

Bash adalah cangkang mirip Bourne. Itu membaca perintah dari ~/.bash_profileketika dipanggil sebagai shell login, dan jika file itu tidak ada¹, ia mencoba membaca ~/.profilesebagai gantinya.

Anda dapat memanggil shell secara langsung kapan saja, misalnya dengan meluncurkan emulator terminal di dalam lingkungan GUI. Jika shell bukan shell login, itu tidak membaca ~/.profile. Ketika Anda memulai bash sebagai shell interaktif (yaitu, bukan untuk menjalankan skrip), bunyinya ~/.bashrc(kecuali ketika dipanggil sebagai shell login, maka itu hanya membaca ~/.bash_profileatau ~/.profile.

Karena itu:

  • ~/.profile adalah tempat untuk meletakkan hal-hal yang berlaku untuk seluruh sesi Anda, seperti program yang ingin Anda mulai ketika Anda masuk (tetapi bukan program grafis, mereka masuk ke file yang berbeda), dan definisi variabel lingkungan.

  • ~/.bashrcadalah tempat untuk meletakkan barang-barang yang hanya berlaku untuk bash itu sendiri, seperti alias dan definisi fungsi, opsi shell, dan pengaturan prompt. (Anda juga bisa meletakkan ikatan kunci di sana, tetapi untuk bash biasanya masuk ~/.inputrc.)

  • ~/.bash_profiledapat digunakan sebagai ganti ~/.profile, tetapi dibaca oleh bash saja, bukan oleh shell lain. (Ini sebagian besar masalah jika Anda ingin file inisialisasi Anda berfungsi pada banyak mesin dan shell login Anda tidak bash pada semuanya.) Ini adalah tempat yang logis untuk memasukkan ~/.bashrcjika shell itu interaktif. Saya merekomendasikan konten berikut di ~/.bash_profile:

    if [ -r ~/.profile ]; then . ~/.profile; fi
    case "$-" in *i*) if [ -r ~/.bashrc ]; then . ~/.bashrc; fi;; esac
    

Pada serikat modern, ada komplikasi tambahan yang terkait dengan ~/.profile. Jika Anda masuk dalam lingkungan grafis (yaitu, jika program tempat Anda mengetik kata sandi Anda berjalan dalam mode grafis), Anda tidak secara otomatis mendapatkan shell login yang berbunyi ~/.profile. Bergantung pada program login grafis, pada window manager atau lingkungan desktop yang Anda jalankan sesudahnya, dan bagaimana distribusi Anda mengonfigurasi program-program ini, Anda ~/.profilemungkin membaca atau tidak. Jika tidak, biasanya ada tempat lain di mana Anda dapat mendefinisikan variabel dan program lingkungan untuk diluncurkan saat Anda masuk, tetapi sayangnya tidak ada lokasi standar.

Perhatikan bahwa Anda dapat melihat di sini dan di sana rekomendasi untuk meletakkan definisi variabel lingkungan di ~/.bashrcatau selalu meluncurkan shell login di terminal. Keduanya adalah ide yang buruk. Masalah yang paling umum dengan salah satu dari ide-ide ini adalah bahwa variabel lingkungan Anda hanya akan ditetapkan dalam program yang diluncurkan melalui terminal, bukan dalam program yang dimulai secara langsung dengan ikon atau menu atau pintasan keyboard.

¹ Untuk kelengkapan, berdasarkan permintaan: jika .bash_profiletidak ada, bash juga mencoba .bash_loginsebelum kembali ke .profile. Jangan ragu untuk melupakannya.

Gilles
sumber
11
+1 untuk pos yang bagus. JUGA terima kasih telah menambahkan bagian tentang "login grafis vs shell masuk" ... Saya punya masalah di mana saya pikir ~ /. Profil akan SELALU mengeksekusi untuk grafis / shell ... tetapi tidak dijalankan ketika pengguna login melalui login grafis. Terima kasih telah memecahkan misteri itu.
Trevor Boyd Smith
4
@Gilles: Bisakah Anda menjelaskan lebih detail, dengan contoh, mengapa menjalankan shell login di setiap terminal adalah ide yang buruk? Apakah ini hanya masalah dengan Linux desktop? (Saya mengetahui bahwa pada OS X Terminal menjalankan shell login setiap waktu, dan saya tidak pernah melihat efek samping (walaupun saya biasanya menggunakan iTerm). Tetapi kemudian saya tidak dapat memikirkan banyak variabel lingkungan yang saya pedulikan di luar terminal. (Mungkin HTTP_PROXY?))
iconoclast
2
@Brandon Jika Anda menjalankan shell login di setiap terminal, itu akan menimpa variabel lingkungan yang disediakan oleh lingkungan. Dalam situasi sehari-hari, Anda bisa lolos begitu saja, tetapi itu akan datang dan menggigit Anda cepat atau lambat, ketika Anda ingin mengatur variabel yang berbeda di terminal (katakanlah, untuk mencoba versi program yang berbeda): menjalankan shell login akan menimpa pengaturan lokal Anda.
Gilles
4
Pernyataan itu ~/.bash_profilebisa digunakan sebagai ganti ~/.profile, tetapi Anda juga harus memasukkan ~/.bashrcjika shell itu interaktif. menyesatkan karena ini adalah masalah ortogonal. Tidak masalah jika Anda menggunakan ~/.bash_profileatau ~/.profileharus memasukkan ~/.bashrcyang Anda gunakan jika Anda ingin pengaturan dari sana berpengaruh di shell login.
Piotr Dobrogost
3
@Gilles Tentu, tetapi cara kalimat itu dirumuskan dalam jawaban menunjukkan bahwa kebutuhan untuk memasukkan ~/.bashrcada hubungannya dengan memilih ~/.bash_profilebukannya ~/.profileyang tidak benar. Jika seseorang memasukkan ~/.bashrcdalam jenis skrip apa pun yang bersumber pada waktu masuk (di sini salah satu ~/.bash_profileatau ~/.profile) karena ia ingin pengaturan ~/.bashrcditerapkan ke shell login dengan cara yang sama mereka diterapkan ke shell non-login.
Piotr Dobrogost
53

Dari artikel singkat ini

Menurut halaman manual bash, .bash_profile dieksekusi untuk shell login, sedangkan .bashrc dieksekusi untuk shell non-login interaktif.

Apa itu shell login atau non-login?

Ketika Anda masuk (mis: ketik nama pengguna dan kata sandi) melalui konsol, baik secara fisik duduk di mesin saat boot, atau secara jarak jauh melalui ssh: .bash_profile dijalankan untuk mengonfigurasi hal-hal sebelum prompt perintah awal.

Tetapi, jika Anda sudah masuk ke mesin Anda dan membuka jendela terminal baru (xterm) di dalam Gnome atau KDE, maka .bashrc dieksekusi sebelum jendela command prompt. .bashrc juga dijalankan ketika Anda memulai instance bash baru dengan mengetik / bin / bash di terminal.

Jarvin
sumber
12
Pembaruan sedikit: 'Dieksekusi' mungkin istilah yang sedikit menyesatkan, keduanya bersumber. Suara yang dieksekusi seperti dijalankan sebagai skrip, fork / exec yadda yadda. Dijalankan dalam konteks shell saat ini. Yang lebih penting, .bashrc dijalankan lebih sering. Ini dijalankan pada setiap skrip bash dijalankan, dan juga jika Anda tidak memiliki .bash_profile. Juga, tergantung bagaimana Anda mengatur xterms Anda, Anda dapat membuat shell yang sumber .bash_profile
Rich Homolka
36

Kembali di masa lalu, ketika pseudo tty tidak pseudo dan sebenarnya, baik, diketik, dan UNIX diakses oleh modem sangat lambat Anda bisa melihat setiap huruf dicetak ke layar Anda, efisiensi sangat penting. Untuk membantu efisiensi, Anda memiliki konsep jendela masuk utama dan jendela apa pun yang Anda gunakan untuk bekerja. Di jendela utama Anda, Anda ingin pemberitahuan ke email baru apa pun, mungkin menjalankan beberapa program lain di latar belakang.

Untuk mendukung ini, shell mengambil file .profilesecara khusus pada 'shell login'. Ini akan melakukan pengaturan sesi khusus, sekali. Bash memperluas ini agak untuk melihat .bash_profile terlebih dahulu sebelum .profile, dengan cara ini Anda bisa menaruh bash hanya hal-hal di sana (sehingga mereka tidak mengacaukan shell Bourne, dll, yang juga melihat .profile). Kerang lain, non-login, hanya akan sumber file rc, .bashrc (atau .kshrc, dll).

Ini sedikit anakronisme sekarang. Anda tidak masuk ke shell utama sebanyak Anda masuk ke jendela manajer gui. Tidak ada jendela utama yang berbeda dari jendela lainnya.

Saran saya - jangan khawatir tentang perbedaan ini, ini didasarkan pada gaya lama menggunakan unix. Hilangkan perbedaan dalam file Anda. Seluruh konten .bash_profile harus:

[ -f $HOME/.bashrc ] && . $HOME/.bashrc

Dan letakkan semua yang Anda ingin atur di .bashrc

Ingat bahwa .bashrc bersumber untuk semua shell, interaktif dan non-interaktif. Anda dapat membuat arus pendek sumber untuk shell non-interaktif dengan meletakkan kode ini di dekat bagian atas .bashrc:

[[ $- != *i* ]] && return

Homolka yang kaya
sumber
6
Ini ide yang buruk, lihat jawaban saya . Secara khusus, variabel lingkungan Anda hanya akan ditetapkan dalam program yang diluncurkan melalui terminal, bukan dalam program yang dimulai secara langsung dengan ikon atau menu atau pintasan keyboard.
Gilles
4
@Gilles Saya tidak mengerti mengapa Anda mengklaim ini. Dengan .$HOME/.bashrcseperti yang ditunjukkan Rich di atas, pengaturan di .bashrcakan tersedia di shell login, dan juga lingkungan desktop. Misalnya, pada sistem Fedora saya, gnome-sessiondimulai sebagai -$SHELL -c gnome-session, begitu .profilejuga dibaca.
Mikel
2
@PiotrDobrogost Oh, ya, ada masalah lain dengan jawaban Rich. Termasuk .bashrcdalam .profilebiasanya tidak berfungsi, karena .profiledapat dieksekusi oleh /bin/shdan bukan bash (mis. Pada Ubuntu untuk login grafis secara default), dan shell itu mungkin tidak interaktif (mis. Untuk login grafis).
Gilles
3
@Gilles re: "termasuk .bashrc dalam .profile" sama sekali tidak direkomendasikan (justru sebaliknya, sebenarnya). Entah jawabannya diedit (sepertinya tidak), atau komentar Anda tidak selaras dengan apa yang dikatakan.
michael
2
Secara umum, +1, tetapi saya akan menambah rekomendasi ke "korsleting ... untuk cangkang non-interaktif" ("dekat bagian atas .bashrc: [[ $- != *i* ]] && return"); Saya suka beberapa dari saya .bashrcdieksekusi bahkan untuk shell non-interaktif, khususnya untuk mengatur env vars, ketika mengeluarkan ssh hostname {command}, sehingga perintah jarak jauh dijalankan dengan benar (meskipun shell tidak interaktif). Tetapi pengaturan lain di kemudian hari .bashrcharus diabaikan. Saya biasanya memeriksa TERM = bodoh dan / atau tidak disetel, dan kemudian membayar lebih awal.
michael
18

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
Daripada memposting jawaban yang sama pada beberapa pertanyaan, lebih disukai jika Anda dapat menyesuaikan jawaban Anda dengan kebutuhan spesifik penanya. Jika jawabannya persis sama untuk kedua pertanyaan maka Anda harus memposting satu jawaban dan memilih untuk menutup pertanyaan lain sebagai duplikat dari yang asli.
Mokubai
1
@Mokubai Pertanyaan lain sudah ditandai sebagai duplikat dari yang ini.
Flimm
@ElipticalView: dengan set melakukan apa-apa, Anda mengacu baris: [ -z "$PS1" ] && return? Tabel dalam jawaban saya adalah memberikan daftar skrip yang dijalankan oleh Bash terlepas dari isi skrip, jika skrip itu sendiri memiliki garis [ -z "$PS1" ] && return, tentu saja itu akan berpengaruh, tetapi saya tidak berpikir itu berarti saya harus mengubah meja.
Flimm
5

KOMENTAR YANG LEBIH BAIK UNTUK KEPALA / DLL / PROFIL

Berdasarkan jawaban Flimm yang luar biasa di atas, saya memasukkan komentar baru ini di kepala profil Debian / etc / saya, (Anda mungkin perlu menyesuaikannya untuk distro Anda.) :

# For BASH: Read down the appropriate column. Executes A, then B, then C, etc.
# The B1, B2, B3 means it executes only the first of those files found.  (A)
# or (B2) means it is normally sourced by (read by and included in) the
# primary file, in this case A or B2.
#
# +---------------------------------+-------+-----+------------+
# |                                 | Interactive | non-Inter. |
# +---------------------------------+-------+-----+------------+
# |                                 | login |    non-login     |
# +---------------------------------+-------+-----+------------+
# |                                 |       |     |            |
# |   ALL USERS:                    |       |     |            |
# +---------------------------------+-------+-----+------------+
# |BASH_ENV                         |       |     |     A      | not interactive or login
# |                                 |       |     |            |
# +---------------------------------+-------+-----+------------+
# |/etc/profile                     |   A   |     |            | set PATH & PS1, & call following:
# +---------------------------------+-------+-----+------------+
# |/etc/bash.bashrc                 |  (A)  |  A  |            | Better PS1 + command-not-found 
# +---------------------------------+-------+-----+------------+
# |/etc/profile.d/bash_completion.sh|  (A)  |     |            |
# +---------------------------------+-------+-----+------------+
# |/etc/profile.d/vte-2.91.sh       |  (A)  |     |            | Virt. Terminal Emulator
# |/etc/profile.d/vte.sh            |  (A)  |     |            |
# +---------------------------------+-------+-----+------------+
# |                                 |       |     |            |
# |   A SPECIFIC USER:              |       |     |            |
# +---------------------------------+-------+-----+------------+
# |~/.bash_profile    (bash only)   |   B1  |     |            | (doesn't currently exist) 
# +---------------------------------+-------+-----+------------+
# |~/.bash_login      (bash only)   |   B2  |     |            | (didn't exist) **
# +---------------------------------+-------+-----+------------+
# |~/.profile         (all shells)  |   B3  |     |            | (doesn't currently exist)
# +---------------------------------+-------+-----+------------+
# |~/.bashrc          (bash only)   |  (B2) |  B  |            | colorizes bash: su=red, other_users=green
# +---------------------------------+-------+-----+------------+
# |                                 |       |     |            |
# +---------------------------------+-------+-----+------------+
# |~/.bash_logout                   |    C  |     |            |
# +---------------------------------+-------+-----+------------+
#
# ** (sources !/.bashrc to colorize login, for when booting into non-gui)

Dan catatan ini ada di kepala masing-masing file pengaturan lainnya untuk merujuknya:

# TIP: SEE TABLE in /etc/profile of BASH SETUP FILES AND THEIR LOAD SEQUENCE

Perlu dicatat saya pikir adalah bahwa Debian / etc / profile oleh sumber default (termasuk) /etc/bash.bashrc (saat itulah /etc/bash.bashrc ada). Jadi skrip login membaca kedua file / etc, sementara non-login hanya membaca bash.bashrc.

Yang juga perlu diperhatikan adalah bahwa /etc/bash.bashrc diatur untuk tidak melakukan apa-apa ketika tidak dijalankan secara interaktif. Jadi kedua file ini hanya untuk skrip interaktif.

Pandangan elips
sumber
4

Logika konfigurasi bash sendiri tidak gila rumit dan dijelaskan dalam jawaban lain di halaman ini, pada serverfault dan di banyak blog. Namun masalahnya adalah apa yang membuat distribusi Linux bash , maksud saya rumit dan berbagai cara mereka mengkonfigurasi bash secara default. http://mywiki.wooledge.org/DotFiles menyebutkan beberapa kebiasaan ini secara singkat. Berikut ini satu contoh jejak pada Fedora 29, ini menunjukkan sumber file mana yang file lainnya dan urutan skenario yang sangat sederhana: menghubungkan dari jauh dengan ssh dan kemudian memulai subkulit lain:

ssh fedora29
 └─ -bash # login shell
      ├── /etc/profile
      |    ├─ /etc/profile.d/*.sh
      |    ├─ /etc/profile.d/sh.local
      |    └─ /etc/bashrc
      ├── ~/.bash_profile
      |    └─ ~/.bashrc
      |          └─ /etc/bashrc
      |
      |
      └─ $ bash  # non-login shell
            └─ ~/.bashrc
                 └─ /etc/bashrc
                       └─ /etc/profile.d/*.sh

Logika paling rumit Fedora adalah di /etc/bashrc. Seperti yang terlihat di atas /etc/bashrcadalah file yang tidak diketahui oleh bash, maksud saya tidak secara langsung. /etc/bashrcTes Fedora apakah:

  • itu bersumber dari shell login,
  • itu bersumber dari shell interaktif,
  • itu sudah bersumber

... dan kemudian melakukan hal-hal yang sangat berbeda tergantung pada itu.

Jika Anda berpikir dapat mengingat grafik di atas maka sangat buruk karena itu tidak cukup: grafik ini hanya menggambarkan satu skenario, hal-hal yang sedikit berbeda terjadi ketika menjalankan skrip non-interaktif atau memulai sesi grafis. Saya telah menghilangkan ~/.profile. Saya telah menghilangkan bash_completionskrip. Untuk alasan kompatibilitas ke belakang, gunakan bash sebagai /bin/shganti /bin/bashmengubah perilakunya. Bagaimana dengan zsh dan kerang lainnya? Dan tentu saja distribusi Linux yang berbeda melakukan hal-hal yang berbeda, misalnya Debian dan Ubuntu datang dengan versi non-standar dari bas , ia memiliki kustomisasi khusus Debian. Ini terutama mencari file yang tidak biasa:/etc/bash.bashrc. Bahkan jika Anda tetap pada satu distribusi Linux saja, ia mungkin berkembang seiring waktu. Tunggu: kami bahkan belum menyentuh macOS, FreeBSD, ... Akhirnya, mari kita pikirkan pengguna yang terjebak dengan cara yang bahkan lebih kreatif, admin mereka telah mengkonfigurasi sistem yang harus mereka gunakan.

Seperti yang didemonstrasikan oleh arus diskusi tanpa henti tentang topik ini, itu adalah tujuan yang hilang. Selama Anda hanya ingin menambahkan nilai-nilai baru, beberapa "coba-coba" cenderung cukup. Kegembiraan yang sebenarnya dimulai ketika Anda ingin memodifikasi dalam satu (pengguna) file sesuatu yang sudah didefinisikan dalam yang lain (di / etc). Kemudian bersiaplah untuk meluangkan waktu merancang solusi yang tidak akan pernah portabel.

Untuk kesenangan terakhir, inilah "grafik sumber" untuk skenario yang sama dan sederhana pada Clear Linux pada Juni 2019:

ssh clearlinux
 └─ -bash # login shell
      ├── /usr/share/defaults/etc/profile
      |    ├─ /usr/share/defaults/etc/profile.d/*
      |    ├─ /etc/profile.d/*
      |    └─ /etc/profile
      ├── ~/.bash_profile
      |
      |
      └─  $ bash   # non-login shell
           ├─ /usr/share/defaults/etc/bash.bashrc
           |      ├─ /usr/share/defaults/etc/profile
           |      |    ├─ /usr/share/defaults/etc/profile.d/*
           |      |    ├─ /etc/profile.d/*
           |      |    └─ /etc/profile
           |      └─ /etc/profile
           └─ ~/.bashrc
Maret
sumber