Mengapa sumber Bash jauh .bash_profile bukan .bashrc

24

Bash Manual mengatakan:

Bash mencoba menentukan kapan dijalankan dengan input standar yang terhubung ke koneksi jaringan, seperti ketika dijalankan oleh daemon shell jarak jauh, biasanya rshd, atau secure shell daemon sshd. Jika Bash menentukan sedang dijalankan dengan cara ini, ia membaca dan mengeksekusi perintah dari ~ / .bashrc, jika file itu ada dan dapat dibaca.

Sumber Bash ini ~/.bashrc:

ssh user@host :

Tapi sumber Bash ini ~/.bash_profile:

ssh user@host

Saya tidak melihat perbedaan dalam dua perintah ini sesuai dengan spesifikasi. Bukankah stdin terhubung ke koneksi jaringan dalam kedua kasus?

Cyker
sumber
2
Meskipun bukan itu yang Anda tanyakan, saya ingin mencatat bahwa ini dianggap praktik yang baik untuk mendapatkan .bashrc dari .bash_profile . Dengan begitu, pengaturan dari .bashrc akan diterapkan terlepas dari apakah bash dimulai sebagai shell login atau shell non-login.
Ilmari Karonen

Jawaban:

44

Shell login pertama kali dibaca /etc/profiledan kemudian ~/.bash_profile.

Shell non-login dibaca dari /etc/bash.bashrcdan kemudian ~/.bashrc.

Mengapa itu penting?

Karena baris ini di man ssh:

Jika perintah ditentukan, ini dijalankan pada host jarak jauh alih-alih shell login.

Dengan kata lain, jika perintah ssh hanya memiliki opsi (bukan perintah), seperti:

ssh user@host

Itu akan memulai shell login, shell login membaca ~/.bash_profile.

Perintah ssh yang memang memiliki perintah , seperti:

ssh user@host :

Di mana perintahnya :(atau tidak melakukan apa-apa).
Itu tidak akan memulai shell login, oleh karena ~/.bashrcitu apa yang akan dibaca.


Stdin jarak jauh

Koneksi tty yang disediakan untuk / dev / stdin di komputer jarak jauh mungkin tty yang sebenarnya atau yang lainnya.

Untuk:

$ 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

Yang berakhir dengan TTY (bukan koneksi jaringan) sebagai bash mulai melihatnya.

Untuk koneksi ssh dengan perintah:

$ 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

Daftar TTY memulai sama, tetapi perhatikan bahwa / etc / profile tidak bersumber.

$ 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]

Yang memberitahu shell bahwa koneksi adalah pipa (bukan koneksi jaringan).

Jadi, dalam kedua kasus pengujian, shell tidak dapat mengetahui bahwa koneksi berasal dari jaringan dan karena itu tidak membaca ~/.bashrc(jika kita hanya berbicara tentang koneksi ke jaringan). Itu membaca ~ / .bashrc, tetapi untuk alasan yang berbeda.

sorontar
sumber
Bukankah kasus no-arg juga memenuhi syarat dijalankan dengan input standar yang terhubung ke koneksi jaringan dan dengan demikian telah ~/.bashrcmembaca?
Cyker
@ Cyker Itu dengan asumsi bahwa shell akan stdin terhubung ke jaringan . Mengapa Anda menganggap itu? (Jawaban diedit, silakan baca).
sorontar
Bagian yang diedit menarik. Sepertinya ssh tidak repot dengan pty saat hanya menjalankan perintah.
Cyker
8

Anda bertanya tentang "mengapa" bukan "bagaimana", jadi saya akan mencoba menjawab dari perspektif itu. Berikut ini akan menjadi alasan mengapa banyak hal terjadi di masa lalu untuk menghasilkan bagaimana mereka terjadi hari ini.


Alasan memiliki dua file startup yang berbeda ("profil" dan "rc") adalah bahwa di masa lalu cara yang umum untuk bekerja pada mesin adalah:

  1. Login dari beberapa terminal nyata atau workstation lain dan dapatkan shell login . Shell ini akan memanggil /etc/profiledan ~/.profiledan setup lingkungan bagi pengguna.

  2. Meminta lingkungan yang diinginkan pengguna untuk masuk. Lingkungan ini bisa menjadi Xorg, tetapi dalam banyak kasus itu adalah multiplexer seperti layar GNU.

  3. Lingkungan (misalnya layar GNU) kemudian akan memanggil shell ekstra (non-login) yang mewarisi lingkungan dari shell login induk.

Itu adalah cara umum untuk masuk ke mesin UNIX selama waktu cshdan bashsedang dikembangkan. Karena itu dianggap sia-sia untuk membaca ~/.profilelagi di kerang yang mewarisi lingkungan.

bashkemudian ditambahkan ~/.bashrcuntuk konfigurasi tambahan untuk shell non-login ini. csh(dan tcsh) tidak pernah menambahkan file "rc" apa pun untuk cangkang non-login. Perhatikan bahwa csh/ tcshtidak shell kompatibel dengan shell bourne (yang merupakan bagian dari POSIX) sementara bashitu. Shell kompatibel bourne lainnya ksh,, menambahkan variabel lingkungan (disebut ENV), yang, jika didefinisikan akan digunakan sebagai file perintah run ("rc") untuk non-login ksh.

Jadi ya, versi yang lebih baru dari shell bourne menambahkan file konfigurasi tambahan sebagai kenyamanan untuk alias dan opsi cepat lainnya yang akan ada di dalam shell yang disandingkan dengan layar GNU (atau serupa) tetapi tidak ada dalam shell yang Anda dapatkan ketika Anda pertama kali memasuki mesin.

Dengan peningkatan manajer tampilan grafis (GDM), diferensiasi antara file "profil" dan file "rc" menjadi tidak berarti karena GDM akan memiliki file inisialisasi sendiri (misalnya ~/.xinitdan ~/.xsession). Kemudian, shell yang dinyatakan dari dalam GDM dapat berupa shell login atau non-login tergantung dari keinginan pengguna, dan kasus di mana shell non-login akan selalu memiliki induk yang merupakan shell login tidak benar lagi.

Tambahan

Salah satu tabel favorit saya tentang perbandingan file startup shell menunjukkan bagaimana shell kompatibel bourne shell menggunakan profilefile sementara shell lain tidak. Ini karena di masa lalu shell awal (yang memulai muxer) perlu shell kompatibel bourne.

grochmal
sumber