Saya perhatikan bahwa ketika saya menjalankan perintah langsung pada host SSH menggunakan ssh <host> <command>
sintaks, saya melihat output .bashrc
tetapi bukan output .bash_profile
(atau .profile
).
Misalnya, jika saya menempatkan perintah berikut di bagian atas kedua file,
echo ${BASH_SOURCE[0]}
dan sumber secara manual .bash_profile
(sumber mana .bashrc
pada gilirannya), saya akan melihat
$ . .bash_profile
.bash_profile
.bashrc
Ini adalah output yang sama yang saya lihat jika saya masuk ke komputer ini dari jarak jauh melalui SSH, menggunakan ssh <host>
bentuk perintah. (Dan jika saya menyimpan di .bash_profile
tempat lain untuk sementara waktu, tak satu pun dari baris ini akan bergema.)
Namun, jika saya menjalankan perintah langsung pada mesin jarak jauh dengan ssh <host> <command>
bentuk ssh
, maka hasilnya akan terlihat seperti ini:
$ ssh <host> echo foo
/home/rlue/.bashrc
foo
Pemahaman saya adalah bahwa perbedaan antara .bash_profile
dan .bashrc
yang pertama adalah untuk shell login sedangkan yang terakhir adalah untuk shell non-login yang interaktif .
Saya telah menyimpulkan yang berikut ini:
ssh <host>
sumber saja.bash_profile
, sementarassh <host> <command>
sumber saja.bashrc
, yang artinya- yang pertama adalah shell login dan yang terakhir tidak.
Apakah kesimpulan ini benar? Mengapa ssh <host> <command>
diperlakukan sebagai shell non-login yang interaktif? Bukankah SSH masih masuk ke mesin jarak jauh untuk menjalankan perintah?
.bashrc
? File itu tidak seharusnya menghasilkan output apa pun. Output apa pun dari.bashrc
dapat merusak semua alat menggunakan ssh sebagai transportasi mereka..bashrc
melemparkan kesalahan, sedangkan baris serupa.bash_profile
tidak. Saya mengambil kesempatan untuk menyelidiki perbedaan sebelum memperbaiki garis yang menyinggung.Jawaban:
OpenSSH (kemungkinan besar apa yang Anda jalankan) memutuskan apakah akan membuat shell login atau tidak, dan itu hanya berlaku jika Anda tidak menjalankan perintah tertentu. Dari
man ssh
:Jadi ini adalah pilihan implementasi untuk server ssh apakah ia ingin membuat shell login atau tidak, dan jika Anda memberikan perintah untuk menjalankannya, itu tidak.
Meskipun
ssh
melakukan login, jika Anda menjalankan perintah dan keluar, itu benar-benar jauh lebih mirip dengan membuat shell hanya untuk menjalankan perintah itu daripada untuk mendapatkan lingkungan login. Tampaknya, mengingat itu, bahwa orang-orang yang menulis OpenSSH memutuskan untuk memperlakukannya seperti tugas semacam itu.Mereka membuat shell non-interaktif, non-login untuk mengeksekusi perintah, karena itulah semangat menjalankan perintah dalam konteks / shell lain. Namun, biasanya, cangkang non-interaktif tidak akan secara otomatis sumber
~/.bashrc
yang jelas terjadi di sini.bash
sebenarnya mencoba membantu kami di sini. Dari dokumensumber
ssh
memang memerlukan login, para pelaksana rupanya memutuskan bahwa dalam keadaan tertentu, misalnya, memintanya untuk mengeksekusi perintah dan kembali, lakukan tidak perlu / mendapat manfaat dari langkah-langkah tambahan yang diambil oleh shell login, dan karenanya mereka melewatinya. Jadi memang ada shell yang berjalan, saya anggap sebagian besar untuk mengatur lingkungan, dan karena shell tidak akan diberikan kepada pengguna yang masuk, mereka memperlakukannya seolah-olah pengguna baru saja memulai shell baru untuk menjalankan itu commandssh <host> <command>
tidak mewarisi lingkungan dari setiap shell login yang ada. Misalnya,$ ssh <host> \$PATH
mengembalikan jalur sebagaimana adanya tanpa sumber.bash_profile
(atau.profile
, seolah-olah) ... Dalam arti praktis, mengapa Anda ingin menghindari langkah itu?PATH
di saya.profile
- bukankah itu persis hal yang Anda ingin dimuat sebelum menjalankan perintah sewenang-wenang pada host jarak jauh?The mengapa perilaku ini terletak pada tingkat lebih rendah dari kerang:
ssh host
( "login shell" kasus) menggunakan pseudoterminal pada remote host, untuk berkomunikasi antarasshd
proses server dan shell;ssh host command
menggunakan pipa di antarasshd
dancommand
, sebagai gantinya. Pseudoterminals diperlukan untuk menggunakan interpreter perintah secara interaktif, seperti shell, atau mode " read-eval-print " dari bahasa scripting; mereka mengimplementasikan banyak fitur ramah-manusia seperti mampu mundur mundur dari kesalahan ketik. Tetapi mereka memiliki lebih banyak overhead dan (tergantung pada konfigurasi) tidak mengizinkan data sewenang-wenang untuk melewati yang tidak dimodifikasi, jadi SSH menghindari menggunakannya ketika interaksi tidak akan terjadi.Kadang-kadang perintah SSH / tidak ada perintah heuristik mendapatkan ini salah; itu bisa diganti dengan
-t
dan-T
switch. Misalnya, untuk masuk ke mesin jarak jauh dan segera memasang kembaliscreen
sesi yang ditangguhkan , yang perlu Anda lakukanssh -t host screen -R
;ssh host screen -R
akan menyebabkanscreen
pengaduan tentang tidak terhubung ke terminal. Saya tidak bisa memikirkan situasi ketika Anda benar-benar ingin menggunakannya-T
, tetapi ada di sana jika Anda pernah menemukannya.sumber
Pertama, Anda perlu melihat berbagai jenis, Anda dapat membaca ini:
/unix/170493/login-non-login-and-interactive-non-interactive-shells
Sekarang jika Anda membuka bashrc Anda, Anda akan melihat di awal ini:
Itu berarti tergantung pada bagaimana Anda mengakses sistem file ini memuat kode di dalamnya atau tidak.
sumber
.bashrc
boleh ditulis agar tidak bersumber jika itu disebut dalam konteks non-interaktif ( yaitu, jika tidak ada "pernyataan cepat" /$PS1
variabel). Tetapissh <host> <command>
jelas tidak interaktif ; artinya, itu tidak memunculkan prompt perintah. Jadi mengapa OpenSSH dirancang untuk membuat non-login, prompt interaktif (yang mencoba mencari sumber.bashrc
) untuk case use yang tampaknya login dan non-interaktif ini ??