Chọn giữa .bashrc, .profile, .bash_profile, v.v [trùng lặp]


197

Câu hỏi này đã có câu trả lời ở đây:

Đây là lúng túng, nhưng sau nhiều năm sử dụng hệ thống POSIX toàn thời gian, tôi vẫn có một thời gian khó khăn để tìm hiểu xem một tùy biến vỏ nên đi ở .bashrc, .profilehoặc ở một nơi khác. Không đề cập đến một số tập tin cấu hình dành riêng cho hệ điều hành như .pam_environment.

Có, tôi biết cách giải đố thông qua tài liệu và tìm hiểu khi mỗi tệp được tải hoặc không được tải. Điều tôi băn khoăn là liệu có ai tập hợp các hướng dẫn toàn diện về cách quyết định tập tin nào để đưa một loại tùy chỉnh nhất định vào không.


6
câu hỏi này không nên được đánh dấu là trùng lặp vì lý do là .profile không có sẵn trong câu hỏi được thêm vào.
Premraj

Câu trả lời:


222

TL; DR:

  • ~/.bash_profilenên siêu đơn giản và chỉ cần tải .profile.bashrc(theo thứ tự đó)

  • ~/.profilecó nội dung KHÔNG liên quan cụ thể đến bash, chẳng hạn như biến môi trường ( PATHvà bạn bè)

  • ~/.bashrccó bất cứ điều gì bạn muốn tại một dòng lệnh tương tác. Dấu nhắc lệnh, EDITORbiến, bash bí danh cho việc sử dụng của tôi

Một vài lưu ý khác:

  • Bất cứ điều gì nên có sẵn cho các ứng dụng đồ họa HOẶC để sh (hoặc bash được gọi là sh) PHẢI ở trong~/.profile

  • ~/.bashrc không được xuất bất cứ thứ gì

  • Bất cứ điều gì chỉ có sẵn để đăng nhập shell nên đi vào ~/.profile

  • Đảm bảo rằng ~/.bash_loginkhông tồn tại.


3
+1, điều này cho phép ~/.profileđặt chính xác môi trường cho các dịch vụ như GDM / LightDM / LXDM chạy rõ ràng / bin / sh.
grawity

12
.bashrcĐầu ra của tôi khá nhiều thứ, bạn có thể nhận xét về điều đó? Cụ thể, tôi nên đặt đầu ra lời chào ở đâu?
Calimo

14
@Calimo: Làm cho nó chỉ xuất nội dung trong chế độ tương tác. Bạn có thể kiểm tra nó bằng cách sử dụng [[ $- == *i* ]], tìm kiếm 'i' trong $-biến đặc biệt . Tất nhiên, nó chỉ quan trọng ở vị trí đầu tiên trên các hệ thống có bash được biên dịch để đọc .bashrcở chế độ không tương tác. (Đó là, Debian chứ không phải Arch.) Nhưng đó là nguyên nhân thường xuyên gây ra các thông báo lỗi bí ẩn khi cố gắng kết nối bằng sftphoặc scphoặc các công cụ tương tự.
grawity

4
Bây giờ tôi đã biết- tại sao .bash_login không tồn tại? Nó làm gì?
tedder42

11
@ tedder42: Nó cũng giống như .bash_profile.profile. Nhưng bash chỉ đọc cái đầu tiên trong số ba. Có nghĩa là, nếu bạn có một .bash_login, thì cả hai .profile.bash_profilesẽ bị bỏ qua một cách bí ẩn.
grawity

54

Trong vài năm qua, tôi đã có rất nhiều thời gian để lãng phí, vì vậy tôi đã nghiên cứu vấn đề này hơn một chút so với chỉ 10 phút. Tôi không biết đây có phải là bố cục tốt nhất không, nó chỉ là một bố cục hoạt động chính xác trong hầu hết các trường hợp.

Những yêu cầu:

  • ~/.profile phải tương thích với bất kỳ / bin / sh - điều này bao gồm bash, dash, ksh, bất cứ thứ gì khác mà một bản phân phối có thể chọn sử dụng.

  • Các biến môi trường phải được đặt trong một tệp được đọc bởi cả hai thông tin đăng nhập bảng điều khiển (tức là vỏ 'đăng nhập') và thông tin đăng nhập đồ họa (tức là các trình quản lý hiển thị như GDM, LightDM hoặc LXDM).

  • Có rất ít điểm trong việc có cả hai ~/.profile~/.bash_profile. Nếu cái sau bị thiếu, bash sẽ vui vẻ sử dụng cái trước, và bất kỳ dòng cụ thể nào của bash đều có thể được bảo vệ bằng một kiểm tra cho $BASHhoặc $BASH_VERSION.

  • Sự tách biệt giữa *profile*rclà cái trước được sử dụng cho các vỏ 'đăng nhập' và cái sau mỗi khi bạn mở một cửa sổ đầu cuối. Tuy nhiên, bash trong chế độ 'đăng nhập' không có nguồn ~/.bashrc, do đó ~/.profilecần phải thực hiện thủ công.

Các đơn giản nhất cấu hình sẽ là:

  • Có một ~/.profilebộ đặt tất cả các biến môi trường (ngoại trừ các biến cụ thể của bash), có thể in một hoặc hai dòng, sau đó nguồn ~/.bashrcnếu được chạy bằng bash, nếu không sử dụng cú pháp tương thích sh.

    xuất TZ = "Châu Âu / Paris"
    xuất EDITOR = "vim"
    nếu ["$ BASH"]; sau đó
        . ~ / .bashrc
    fi
    thời gian hoạt động
    
  • Yêu cầu ~/.bashrcthực hiện bất kỳ thiết lập cụ thể nào về vỏ, được bảo vệ bằng chế độ kiểm tra chế độ tương tác để tránh phá vỡ mọi thứ như sftptrên Debian (nơi bash được biên dịch với tùy chọn tải ~/.bashrcngay cả đối với các vỏ không tương tác):

    [[$ - == * i *]] || trả về 0
    
    PS1 = '\ h \ w \ $'
    
    start () {sudo dịch vụ "$ 1" bắt đầu; }
    

Tuy nhiên, cũng có vấn đề mà một số lệnh không tương tác (ví dụ ssh <host> ls) bỏ qua ~/.profile, nhưng các biến môi trường sẽ rất hữu ích với chúng.

  • Một số bản phân phối (ví dụ Debian) biên dịch bash của họ với tùy chọn tìm nguồn ~/.bashrccho các thông tin đăng nhập không tương tác đó. Trong trường hợp này, tôi thấy hữu ích khi di chuyển tất cả các biến môi trường (các export ...dòng) sang một tệp riêng biệt ~/.environvà lấy nguồn từ cả hai .profile.bashrc, với một người bảo vệ để tránh thực hiện hai lần:

    nếu như ! ["$ PREFIX"]; sau đó    # hoặc $ EDITOR, hoặc $ TZ, hoặc ... 
        . ~ / .envir            # nói chung bất kỳ biến nào mà .envir tự đặt
    fi
    
  • Thật không may, đối với các bản phân phối khác (ví dụ Arch), tôi đã không tìm thấy một giải pháp rất tốt. Một khả năng là sử dụng mô-đun PAM (được bật theo mặc định) pam_env, bằng cách đưa vào phần sau ~/.pam_environment:

    BASH_ENV =. /. Môi trường         # không phải là một lỗi đánh máy; nó cần phải là một con đường, nhưng ~ sẽ không hoạt động
    

    Sau đó, tất nhiên, cập nhật ~/.environlên unset BASH_ENV.


Phần kết luận? Vỏ ốc là một nỗi đau. Biến môi trường là một nỗi đau. Tùy chọn thời gian biên dịch cụ thể phân phối là một nỗi đau lớn trong ass.


2
+1 cho đoạn cuối cùng, nhưng tôi thích tìm nguồn cung ứng .profile.bashrctừ .bash_profilevà giữ .profilesạch sẽ.
nyuszika7h

@ nyuszika7h: My .profile sạch rồi , cảm ơn.
grawity

1
Lưu ý nhận xét lại mỗi khi bạn mở một cửa sổ là cách khác cho OSX
Đánh dấu

1
"Có rất ít điểm trong việc có cả hai ~/.profile~/.bash_profile": Tôi không đồng ý. Xem câu trả lời của Dan cho lý do tại sao.
rubenvb

@rubenvb Bạn có thể trích dẫn phần có liên quan? Tôi nghĩ thật tốt khi chỉ có một .profilevà bảo vệ những bashphần đặc biệt với những điều kiện.
Kelvin

36

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

Đối với Bash, họ làm việc như sau. Đọc xuống cột thích hợp. Thực thi A, rồi B, rồi C, v.v ... B1, B2, B3 có nghĩa là nó chỉ thực thi đầu tiên trong số các 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      |           |      |
+----------------+-----------+-----------+------+

Cái này đẹp đấy. Điều quan trọng cần lưu ý là thường /etc/profilegọi /etc/bash.bashrc~/.profilegọi ~.bashrc. Vì vậy, hiệu quả /etc/bash.bashrc~/.bashrcđang được thực hiện cho Đăng nhập tương tác.
wvducky

Lưu ý rằng một số bản phân phối dường như ghi đè lên lược đồ này (với hậu quả lạ) - xem ví dụ:
bugreport

Btw. ít nhất là với bash, không có tệp nào trong số đó được thực thi khi bash được gọi qua/bin/sh
JepZ

@JepZ Bạn nói đúng, đó là những gì cột thứ ba "Script" giải thích.
Flimm

1
@Flimm Chà, cột 'Tập lệnh' mô tả những gì xảy ra khi bạn bắt đầu một tập lệnh không tương tác thông qua bash (ví dụ / bin / bash). Tuy nhiên, nếu bạn bắt đầu một tập lệnh thông qua sh (và / bin / sh là một liên kết tượng trưng đến / bin / bash) thì không có điều nào ở trên được thực thi (không phải chẵn BASH_ENV). Đoạn liên quan của trang bash man có thể được tìm thấy bằng cách tìm kiếm If bash is invoked with the name sh.
JepZ

21

Tôi cung cấp cho bạn các hướng dẫn "toàn diện" của tôi:

  • Tạo .bash_profile.profiletải .bashrcnếu nó tồn tại, sử dụng ví dụ [ -r $HOME/.bashrc ] && source $HOME/.bashrc
  • Đặt mọi thứ khác vào .bashrc.
  • Đừng lo lắng nữa.
  • Cứ sau bốn năm, hãy dành mười phút để nghiên cứu chính câu hỏi này trước khi từ bỏ và quay lại "không đáng lo ngại".

EDIT: Đã thêm trích dẫn sợ hãi để "toàn diện" trong trường hợp bất cứ ai bị cám dỗ để tin nó. ;)


3
Có cả hai .bash_profile.profilelà một chút dư thừa; bạn chỉ cần cái sau Tuy nhiên, bạn cần phải làm cho nó / bin / sh-Proof : if [ "$BASH" ] && [ -r ~/.bashrc ]; then . ~/.bashrc; fi, vì có các chương trình (cụ thể là gdm / lightdm) tự lấy nguồn tệp từ tập lệnh / bin / sh. Điều này cũng có nghĩa là môi trường được giữ trong .bashrcđó sẽ không hiệu quả. Phải -1, vì các hướng dẫn "toàn diện" của bạn sẽ không hoạt động trên nhiều hệ thống, vì tôi đã tìm ra cách khó khăn nhiều lần.
grawity

Không có vấn đề gì, tôi vui vẻ trả -1 cho một câu trả lời không chỉ đơn thuần là "toàn diện", và bạn chắc chắn đã đạt được danh hiệu đó.
Cơ khí

0

Tôi đã từ bỏ việc cố gắng tìm ra cái này và tạo ra một kịch bản ( ~/.shell-setup) mà tôi lấy từ tất cả những cái khác.

Cách tiếp cận này đòi hỏi ~/.shell-setupphải có hai tính năng:

  1. Chỉ chạy một lần, ngay cả khi có nguồn gốc nhiều lần (sử dụng Bao gồm lính canh )
  2. Không tạo ra bất kỳ đầu ra không mong muốn nào (phát hiện khi đầu ra ổn)

# 1 là khá chuẩn, mặc dù có thể không được sử dụng nhiều trong shell script.

# 2 là khó khăn hơn. Đây là những gì tôi sử dụng trong bash:

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

Thật không may, tôi không nhớ làm thế nào tôi nghĩ ra điều đó, hoặc tại sao phát hiện ra một vỏ tương tác là không đủ.


-2

Đặt mọi thứ vào .bashrcvà sau đó lấy nguồn .bashrctừ.profile

Từ trang bash man (trên OS X 10.9):

Khi một vỏ tương tác không phải là vỏ đăng nhập được khởi động, bash sẽ đọc và thực thi các lệnh từ ~ / .bashrc, nếu tệp đó tồn tại. Điều này có thể bị ức chế bằng cách sử dụng tùy chọn --norc. Tùy chọn tệp --rcfile sẽ buộc bash đọc và thực thi các lệnh từ tệp thay vì ~ / .bashrc

Các văn bản trên là lý do tại sao mọi thứ được đưa vào .bashrc. Tuy nhiên, có một chút hành vi khác nhau khi bạn xử lý một vỏ đăng nhập. Một lần nữa, trích dẫn từ trang người đàn ông:

Khi bash được gọi dưới dạng shell đăng nhập tương tác hoặc dưới dạng shell không tương tác với tùy chọn --login, trước tiên, nó sẽ đọc và thực thi các lệnh từ tệp / etc / profile, nếu tệp đó tồn tại. Sau khi đọc tệp đó, nó tìm ~ / .bash_profile, ~ / .bash_login và ~ / .profile, theo thứ tự đó, đọc và thực thi các lệnh từ lệnh đầu tiên tồn tại và có thể đọc được. Tùy chọn --noprofile có thể được sử dụng khi trình bao bắt đầu ngăn chặn hành vi này.

.profileđược đọc cho shell đăng nhập, nhưng .bashrckhông. Sao chép tất cả những thứ trong đó .bashrclà xấu ™ vì vậy chúng tôi cần phải cung cấp nguồn đó .profileđể hành vi được nhất quán.

Tuy nhiên, bạn không muốn lấy nguồn .bashrctừ .profilevô điều kiện. Xin vui lòng xem các ý kiến ​​và câu trả lời khác để biết thêm chi tiết.


4
-1, KHÔNG lấy nguồn .bashrctừ .profile. Xem câu trả lời của @ DanRabinowitz.
nyuszika7h

Ít nhất là không vô điều kiện.
nyuszika7h

[ -n "$BASH" -a -f ~/.bashrc ] && . ~/.bashrcsẽ là một oneliner ngọt ngào cho .profile.
John WH Smith

@ nyuszika7h, Tại sao không? Mọi người dường như đề nghị làm như vậy.
Pacerier
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.