Câu hỏi Sự khác biệt giữa .bashrc và .bash_profile


Sự khác biệt giữa .bashrc và .bash_profile và tôi nên sử dụng cái nào?


401
2017-09-02 14:40


gốc


Xem thêm câu hỏi tương tự tại ubuntu.stackexchange.com/questions/1528/bashrc-or-bash-profile - Stefan Lasiewski
Nếu bạn muốn có một lời giải thích hoàn chỉnh hơn cũng liên quan đến .profile, hãy xem câu hỏi này: superuser.com/questions/789448/… - Flimm
Câu trả lời này cũng bao gồm một số khía cạnh stackoverflow.com/questions/415403/… - Sergey Voronezhskiy


Các câu trả lời:


Theo truyền thống, khi bạn đăng nhập vào hệ thống Unix, hệ thống sẽ bắt đầu một chương trình cho bạn. Chương trình đó là một trình bao, tức là một chương trình được thiết kế để khởi động các chương trình khác. Đó là một shell dòng lệnh: bạn bắt đầu một chương trình khác bằng cách gõ tên của nó. Trình bao mặc định, một trình bao Bourne, đọc lệnh từ ~/.profile khi nó được gọi là shell đăng nhập.

Bash là một shell giống Bourne. Nó đọc lệnh từ ~/.bash_profile khi nó được gọi là shell đăng nhập và nếu tệp đó không tồn tại, nó sẽ cố đọc ~/.profile thay thế.

Bạn có thể gọi trực tiếp một trình bao bất kỳ lúc nào, ví dụ bằng cách khởi chạy trình mô phỏng đầu cuối bên trong môi trường GUI. Nếu shell không phải là shell đăng nhập, shell không đọc ~/.profile. Khi bạn bắt đầu bash dưới dạng một trình tương tác (tức là, không chạy tập lệnh), nó sẽ đọc ~/.bashrc (trừ khi được gọi là shell đăng nhập, nó chỉ đọc ~/.bash_profile hoặc là ~/.profile.

Vì thế:

  • ~/.profile là nơi đặt những thứ áp dụng cho toàn bộ phiên của bạn, chẳng hạn như các chương trình bạn muốn bắt đầu khi bạn đăng nhập (nhưng không phải là các chương trình đồ họa, chúng đi vào một tệp khác) và định nghĩa biến môi trường.

  • ~/.bashrc là nơi để đưa những thứ chỉ áp dụng để bash chính nó, chẳng hạn như bí danh và định nghĩa chức năng, tùy chọn trình bao và cài đặt nhanh. (Bạn cũng có thể đặt các ràng buộc chính ở đó, nhưng đối với bash chúng thường đi vào ~/.inputrc.)

  • ~/.bash_profile có thể được sử dụng thay vì ~/.profile, nhưng nó chỉ được đọc bởi bash, không phải bởi bất kỳ trình bao nào khác. (Điều này chủ yếu là một mối quan tâm nếu bạn muốn các tệp khởi tạo của bạn hoạt động trên nhiều máy và vỏ đăng nhập của bạn không bị bash trên tất cả chúng.) Đây là một nơi hợp lý để bao gồm ~/.bashrc nếu trình bao tương tác. Tôi đề nghị các nội dung sau trong ~/.bash_profile:

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

Trên các thông báo hiện đại, có thêm một biến chứng liên quan đến ~/.profile. Nếu bạn đăng nhập vào một môi trường đồ họa (có nghĩa là, nếu chương trình mà bạn gõ mật khẩu của bạn đang chạy trong chế độ đồ họa), bạn không tự động nhận được một vỏ đăng nhập mà đọc ~/.profile. Tùy thuộc vào chương trình đăng nhập đồ họa, trên trình quản lý cửa sổ hoặc môi trường màn hình bạn chạy sau đó và cách phân phối của bạn đã định cấu hình các chương trình này, ~/.profile có thể hoặc không thể đọc được. Nếu không, thường có một nơi khác mà bạn có thể xác định các biến môi trường và chương trình để khởi chạy khi bạn đăng nhập, nhưng tiếc là không có vị trí chuẩn.

Lưu ý rằng bạn có thể thấy ở đây và có các đề xuất để đưa định nghĩa biến môi trường vào ~/.bashrc hoặc luôn khởi chạy các shell đăng nhập trong các thiết bị đầu cuối. Cả hai đều là ý tưởng tồi. Vấn đề phổ biến nhất với một trong những ý tưởng này là các biến môi trường của bạn sẽ chỉ được đặt trong các chương trình được khởi chạy qua thiết bị đầu cuối, không phải trong các chương trình được bắt đầu trực tiếp bằng biểu tượng hoặc menu hoặc phím tắt.

¹  Để hoàn thành, theo yêu cầu: nếu .bash_profile không tồn tại, bash cũng cố gắng .bash_logintrước khi quay trở lại .profile. Hãy quên nó tồn tại.  


471
2017-09-02 19:23



1 cho bài đăng tốt. CSONG cảm ơn bạn đã thêm phần "login graphic vs login shell" ... Tôi đã gặp vấn đề nơi tôi nghĩ ~ / .profile LUÔN LUÔN sẽ thực thi cho đồ họa / shell ... nhưng nó không thực thi khi người dùng đăng nhập thông qua đăng nhập đồ họa. Cảm ơn bạn đã giải quyết bí ẩn đó. - Trevor Boyd Smith
@ Gilles: Bạn có thể giải thích chi tiết hơn không, với các ví dụ, tại sao chạy một shell đăng nhập trong mỗi terminal là một ý tưởng tồi? Đây có phải chỉ là vấn đề với Linux trên máy tính để bàn không? (Tôi thu thập rằng trên OS X Terminal chạy một vỏ đăng nhập mỗi lần, và tôi đã không bao giờ nhận thấy bất kỳ tác dụng phụ (mặc dù tôi thường sử dụng iTerm ).Nhưng sau đó tôi không thể nghĩ ra nhiều biến môi trường tôi muốn quan tâm bên ngoài một thiết bị đầu cuối. (Có thể là HTTP_PROXY?)) - iconoclast
@Brandon Nếu bạn chạy một shell đăng nhập trong mỗi terminal, nó sẽ ghi đè lên các biến môi trường do môi trường cung cấp. Trong các tình huống hàng ngày, bạn có thể thoát khỏi nó, nhưng nó sẽ đến và cắn bạn sớm hay muộn, khi bạn muốn thiết lập các biến khác nhau trong một thiết bị đầu cuối (nói, để thử một phiên bản khác của một chương trình): chạy một shell đăng nhập sẽ ghi đè cài đặt cục bộ của bạn. - Gilles
Tuyên bố ~/.bash_profile có thể được sử dụng thay vì ~/.profile, nhưng bạn cũng cần phải bao gồm ~/.bashrc nếu trình bao tương tác. gây hiểu nhầm vì đây là những vấn đề trực giao. Không có vấn đề nếu bạn sử dụng ~/.bash_profile hoặc là ~/.profile bạn phải bao gồm ~/.bashrc trong một trong những bạn sử dụng nếu bạn muốn cài đặt từ đó để có hiệu lực trong vỏ đăng nhập. - Piotr Dobrogost
@ Gilles Chắc chắn, nhưng cách câu được xây dựng trong câu trả lời cho thấy rằng sự cần thiết phải bao gồm ~/.bashrc có liên quan đến việc chọn ~/.bash_profile thay vì ~/.profile Điều đó không đúng sự thật. Nếu ai đó bao gồm ~/.bashrc trong bất kỳ loại kịch bản nào có nguồn gốc tại thời điểm đăng nhập (ở đây là ~/.bash_profile hoặc là ~/.profile) là vì anh ấy muốn cài đặt từ ~/.bashrc được áp dụng cho shell đăng nhập giống như cách chúng được áp dụng cho shell không đăng nhập. - Piotr Dobrogost


Từ đây bài viết ngắn

Theo trang bash man,   .bash_profile được thực thi để đăng nhập   trong khi .bashrc được thực hiện cho   tương tác không đăng nhập shells.

Vỏ đăng nhập hoặc không đăng nhập là gì?

Khi bạn đăng nhập (ví dụ: nhập tên người dùng và   mật khẩu) thông qua bảng điều khiển   thể chất ngồi ở máy khi   khởi động, hoặc từ xa thông qua ssh:   .bash_profile được thực hiện để định cấu hình   mọi thứ trước lệnh ban đầu   lời nhắc.

Nhưng, nếu bạn đã đăng nhập vào   máy của bạn và mở một thiết bị đầu cuối mới   cửa sổ (xterm) bên trong Gnome hoặc KDE,   sau đó .bashrc được thực thi trước   nhắc lệnh cửa sổ. .bashrc cũng là   chạy khi bạn bắt đầu một trường hợp bash mới   bằng cách gõ / bin / bash trong một thiết bị đầu cuối.


50
2017-09-02 14:54



Cập nhật nhẹ: 'Đã thực thi' có lẽ là một thuật ngữ hơi gây hiểu lầm, cả hai đều có nguồn gốc. Các âm thanh được thực thi giống như nó được chạy dưới dạng tập lệnh, fork / exec yadda yadda. Nó chạy trong ngữ cảnh của shell hiện tại Quan trọng hơn, .bashrc được chạy thường xuyên hơn nhiều. Nó chạy trên mọi tập lệnh bash, và nếu bạn không có tệp .bash_profile. Ngoài ra, tùy thuộc vào cách bạn thiết lập xterms của bạn, bạn có thể tạo một trình bao mà nguồn .bash_profile - Rich Homolka


Quay trở lại những ngày cũ, khi pseudo tty không phải là giả và thực sự, tốt, đánh máy, và UNIX được truy cập bằng modem rất chậm, bạn có thể thấy mỗi chữ được in trên màn hình của bạn, hiệu quả là tối quan trọng. Để giúp hiệu quả phần nào bạn đã có một khái niệm về một cửa sổ đăng nhập chính và bất kỳ cửa sổ nào khác bạn đã sử dụng để thực sự hoạt động. Trong cửa sổ chính của bạn, bạn muốn thông báo cho bất kỳ thư mới nào, có thể chạy một số chương trình khác trong nền.

Để hỗ trợ điều này, các trình bao có nguồn gốc một tệp .profile cụ thể trên 'vỏ đăng nhập'. Điều này sẽ làm việc đặc biệt, một lần thiết lập phiên. Bash mở rộng phần này để xem trước .bash_profile trước .profile, theo cách này bạn có thể đặt bash chỉ những thứ trong đó (vì vậy chúng không làm hỏng Bourne shell, v.v., cũng xem xét .profile). Các trình bao khác, không đăng nhập, sẽ chỉ nguồn tệp rc, .bashrc (hoặc .kshrc, v.v.).

Đây là một chút của một lỗi thời bây giờ. Bạn không đăng nhập vào một shell chính nhiều như bạn đăng nhập vào một trình quản lý cửa sổ gui. Không có cửa sổ chính nào khác với bất kỳ cửa sổ nào khác.

Đề xuất của tôi - đừng lo lắng về sự khác biệt này, nó dựa trên phong cách cũ của việc sử dụng unix. Loại bỏ sự khác biệt trong các tập tin của bạn. Toàn bộ nội dung của .bash_profile phải là:

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

Và đặt mọi thứ bạn thực sự muốn đặt vào .bashrc

Hãy nhớ rằng bashrc có nguồn gốc cho tất cả các shell, tương tác và không tương tác. Bạn có thể ngắn mạch tìm nguồn cung ứng cho vỏ không tương tác bằng cách đặt mã này ở gần đầu .bashrc:

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


34
2017-09-02 18:10



Đây là một ý tưởng tồi, hãy xem câu trả lời của tôi. Đặc biệt, các biến môi trường của bạn sẽ chỉ được đặt trong các chương trình được khởi chạy qua thiết bị đầu cuối, không phải trong các chương trình được bắt đầu trực tiếp bằng biểu tượng hoặc menu hoặc phím tắt. - Gilles
@ Gilles Tôi không hiểu tại sao bạn yêu cầu điều này. Với .$HOME/.bashrc như Rich đã trình bày ở trên, cài đặt trong .bashrc sẽ có sẵn trong shell đăng nhập, và do đó môi trường máy tính để bàn là tốt. Ví dụ, trên hệ thống Fedora của tôi, gnome-session được bắt đầu là -$SHELL -c gnome-session, vì thế .profile được đọc. - Mikel
@PiotrDobrogost Oh, vâng, có một vấn đề khác với câu trả lời của Rich. Kể cả .bashrc trong .profile thường không hiệu quả, bởi vì .profile có thể được thực hiện bởi /bin/sh và không bash (ví dụ: trên Ubuntu để đăng nhập đồ họa theo mặc định) và vỏ đó có thể không tương tác (ví dụ: đối với thông tin đăng nhập đồ họa). - Gilles
@Gilles lại: "bao gồm .bashrc trong .profile" không phải là ở tất cả những gì được đề nghị (hoàn toàn ngược lại, trên thực tế). Hoặc câu trả lời đã được chỉnh sửa (nó không xuất hiện như vậy), hoặc bình luận của bạn không phù hợp với những gì đang được nói. - michael
Nói chung, +1, nhưng tôi sẽ thêm vào đề xuất "ngắn mạch ... cho các hệ vỏ không tương tác" ("ở gần đầu .bashrc: [[ $- != *i* ]] && return"); Tôi thích một số .bashrc sẽ được thực thi ngay cả đối với các shell không tương tác, đặc biệt để đặt các vv env, khi phát hành ssh hostname {command}, để các lệnh từ xa được thực thi đúng cách (mặc dù trình bao không tương tác). Nhưng các cài đặt khác sau này trong .bashrc nên bỏ qua. Tôi thường kiểm tra TERM = câm và / hoặc bỏ đặt, và sau đó bảo lãnh sớm. - michael


Có một cái nhìn tại đây bài đăng trên blog tuyệt vời của ShreevatsaR. Đây là một trích xuất, nhưng đi đến bài đăng blog, nó bao gồm một lời giải thích cho các thuật ngữ như "đăng nhập shell", một biểu đồ dòng chảy, và một bảng tương tự cho Zsh.

Đối với Bash, chúng hoạt động như sau. Đọc xuống cột thích hợp. Thực thi A, rồi B, rồi C, vv. B1, B2, B3 có nghĩa là nó chỉ thực thi đầu tiên của những tệp được tìm thấy.

+----------------+-----------+-----------+------+
|                |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      |           |      |
+----------------+-----------+-----------+------+

14
2017-07-13 08:53



Thay vì đăng cùng một câu trả lời cho nhiều câu hỏi, nó sẽ được ưu tiên hơn nếu bạn có thể điều chỉnh câu trả lời cho các nhu cầu cụ thể của người hỏi. Nếu câu trả lời giống hệt nhau cho cả hai câu hỏi thì bạn nên đăng một câu trả lời và bỏ phiếu để đóng các câu hỏi khác dưới dạng bản sao của bản gốc. - Mokubai♦
@Mokubai Câu hỏi khác đã được đánh dấu là bản sao của câu hỏi này. - Flimm
@ElipticalView: bằng cách đặt để không làm gì, bạn đang đề cập đến dòng: [ -z "$PS1" ] && return? Bảng trong câu trả lời của tôi là đưa ra danh sách các tập lệnh được chạy bởi Bash bất kể nội dung của tập lệnh, nếu bản thân tập lệnh có dòng [ -z "$PS1" ] && return, tất nhiên điều đó sẽ có hiệu lực, nhưng tôi không nghĩ điều đó có nghĩa là tôi nên thay đổi bảng. - Flimm


MỘT BÌNH LUẬN TỐT HƠN CHO TÊN / ETC / HỒ SƠ

Xây dựng trên câu trả lời tuyệt vời của Flimm ở trên, tôi đã chèn nhận xét mới này vào phần đầu của Debian / etc / profile của tôi, (bạn có thể cần phải điều chỉnh nó cho bản phân phối của bạn.):

# 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)

Và lưu ý này ở phần đầu của mỗi tệp thiết lập khác để tham chiếu đến nó:

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

Đáng chú ý Tôi nghĩ rằng Debian / etc / profile theo các nguồn mặc định (bao gồm) /etc/bash.bashrc (đó là khi /etc/bash.bashrc tồn tại). Vì vậy, kịch bản đăng nhập đọc cả tệp / etc, trong khi không đăng nhập chỉ đọc bash.bashrc.

Cũng lưu ý rằng /etc/bash.bashrc được thiết lập để không làm gì khi nó không chạy tương tác. Vì vậy, hai tệp này chỉ dành cho các tập lệnh tương tác.


3
2017-10-18 18:13