Tại sao nguồn Bash từ xa .bash_profile thay vì .bashrc


24

Hướng dẫn Bash nói:

Bash cố gắng xác định khi nào nó đang được chạy với đầu vào tiêu chuẩn của nó được kết nối với kết nối mạng, như khi được thực thi bởi trình nền shell từ xa, thường là rshd hoặc sshd shell shell an toàn. Nếu Bash xác định nó đang được chạy theo kiểu này, nó sẽ đọc và thực thi các lệnh từ ~ / .bashrc, nếu tệp đó tồn tại và có thể đọc được.

Nguồn Bash này ~/.bashrc:

ssh user@host :

Nhưng nguồn Bash này ~/.bash_profile:

ssh user@host

Tôi không thấy sự khác biệt trong hai lệnh này theo thông số kỹ thuật. Không phải stdin được kết nối với kết nối mạng trong cả hai trường hợp?


2
Mặc dù đó không phải là những gì bạn đang hỏi, tôi muốn lưu ý rằng nó được coi là cách thực hành tốt để lấy .bashrc từ .bash_profile . Theo cách đó, các cài đặt từ .bashrc sẽ được áp dụng bất kể bash được bắt đầu như là vỏ đăng nhập hay vỏ không đăng nhập.
Ilmari Karonen

Câu trả lời:


44

Một vỏ đăng nhập đầu tiên đọc /etc/profilevà sau đó ~/.bash_profile.

Một vỏ không đăng nhập đọc từ /etc/bash.bashrcvà sau đó ~/.bashrc.

Tại sao điều đó quan trọng?

Vì dòng này trong man ssh:

Nếu lệnh được chỉ định, nó được thực thi trên máy chủ từ xa thay vì vỏ đăng nhập.

Nói cách khác, nếu lệnh ssh chỉ có các tùy chọn (không phải lệnh), như:

ssh user@host

Nó sẽ bắt đầu một vỏ đăng nhập, một vỏ đăng nhập đọc ~/.bash_profile.

Một lệnh ssh có lệnh , như:

ssh user@host :

Trường hợp lệnh là :(hoặc không làm gì).
Nó sẽ không bắt đầu một vỏ đăng nhập, do đó ~/.bashrclà những gì sẽ được đọc.


Từ xa stdin

Kết nối tty được cung cấp cho / dev / stdin trong máy tính từ xa có thể là một tty thực tế hoặc một cái gì đó khác.

Dành cho:

$ ssh sorontar@localhost
/etc/profile sourced

$ ls -la /dev/stdin
lrwxrwxrwx 1 root root 15 Dec 24 03:35 /dev/stdin -> /proc/self/fd/0

$ ls -la /proc/self/fd/0
lrwx------ 1 sorontar sorontar 64 Dec 24 19:34 /proc/self/fd/0 -> /dev/pts/3

$ ls -la /dev/pts/3
crw--w---- 1 sorontar tty 136, 3 Dec 24 19:35 /dev/pts/3

Kết thúc bằng TTY (không phải kết nối mạng) khi bash bắt đầu nhìn thấy nó.

Đối với kết nối ssh với lệnh:

$ ssh sorontar@localhost 'ls -la /dev/stdin'
sorontar@localhost's password: 
lrwxrwxrwx 1 root root 15 Dec 24 03:35 /dev/stdin -> /proc/self/fd/0

Danh sách của TTY bắt đầu giống nhau, nhưng lưu ý rằng / etc / profile không có nguồn gốc.

$ ssh sorontar@localhost 'ls -la /proc/self/fd/0'
sorontar@localhost's password:
lr-x------ 1 sorontar sorontar 64 Dec 24 19:39 /proc/self/fd/0 -> pipe:[6579259]

Nó báo cho vỏ rằng kết nối là một đường ống (không phải là kết nối mạng).

Vì vậy, trong cả hai trường hợp thử nghiệm, shell không thể biết rằng kết nối là từ một mạng và do đó không đọc được ~/.bashrc(nếu chúng ta chỉ nói về kết nối với mạng). Nó đọc ~ / .bashrc, nhưng vì một lý do khác.


Không phải trường hợp không tranh luận cũng đủ điều kiện được chạy với đầu vào tiêu chuẩn của nó được kết nối với kết nối mạng và do đó đã ~/.bashrcđọc?
Cyker

@Cyker Giả sử shell sẽ có stdin kết nối với mạng . Tại sao bạn cho rằng? (Trả lời chỉnh sửa, xin vui lòng đọc).
sorontar

Phần chỉnh sửa là Thú vị. Có vẻ như ssh không bận tâm với pty khi chỉ cần thực hiện một lệnh.
Cyker

8

Bạn hỏi về "tại sao" chứ không phải "làm thế nào", vì vậy tôi sẽ cố gắng trả lời từ quan điểm đó. Sau đây sẽ là một lý do hợp lý về lý do tại sao mọi thứ xảy ra trong quá khứ để dẫn đến cách chúng xảy ra ngày hôm nay.


Lý do để có hai tệp khởi động khác nhau ("hồ sơ" và "RC") là vì trước đây cách làm việc chung trên máy là:

  1. Đăng nhập từ một số loại thiết bị đầu cuối thực hoặc máy trạm khác và nhận được một vỏ đăng nhập . Shell này sẽ gọi /etc/profile~/.profilethiết lập môi trường cho người dùng.

  2. Gọi môi trường người dùng muốn vào. Môi trường này có thể là Xorg, nhưng trong hầu hết các trường hợp, nó là một bộ ghép kênh như màn hình GNU.

  3. Sau đó, môi trường (ví dụ màn hình GNU) sẽ gọi các shell bổ sung (không đăng nhập) kế thừa môi trường từ shell đăng nhập cha.

Đó là cách phổ biến để đăng nhập vào máy UNIX trong thời gian cshbashđang được phát triển. Do đó, nó được coi là lãng phí khi đọc ~/.profilelại trong các shell đang kế thừa môi trường.

bashsau đó thêm vào ~/.bashrccấu hình bổ sung cho các shell không đăng nhập này. csh(và tcsh) không bao giờ thêm bất kỳ loại tệp "RC" nào cho trình bao không đăng nhập. Lưu ý rằng csh/ tcshkhông phải là vỏ tương thích với vỏ bourne (là một phần của POSIX) trong khi đó bash. Một shell tương thích bourne khác ksh, đã thêm một biến môi trường (được gọi là ENV), nếu được định nghĩa sẽ được sử dụng như một tệp lệnh chạy ("rc") để không đăng nhập ksh.

Vì vậy, vâng, các phiên bản mới hơn của bourne shell đã thêm tệp cấu hình bổ sung để thuận tiện cho các bí danh và các tùy chọn nhanh khác sẽ xuất hiện bên trong các vỏ được điều khiển bởi màn hình GNU (hoặc tương tự) nhưng không có trong vỏ bạn nhận được khi mới nhập máy móc.

Với sự gia tăng của các trình quản lý hiển thị đồ họa (GDM), sự khác biệt giữa các tệp "hồ sơ" và tệp "RC" trở nên vô nghĩa vì GDM sẽ có các tệp khởi tạo riêng (ví dụ ~/.xinit~/.xsession). Sau đó, các shell được nêu từ bên trong GDM có thể là các shell đăng nhập hoặc không đăng nhập tùy thuộc vào ý thích của người dùng và trường hợp trong đó shell không đăng nhập sẽ luôn có cha mẹ là shell đăng nhập không còn đúng nữa.

Thêm

Một trong những bảng yêu thích của tôi về so sánh tệp khởi động shell cho thấy cách các shell tương thích shell bourne sử dụng các profiletệp trong khi các shell khác thì không. Điều này là do trong quá khứ, lớp vỏ ban đầu (lớp khởi động muxer) cần phải là lớp vỏ tương thích bourne.

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.