Saya mengerti perbedaan mendasar antara shell interaktif dan shell non-interaktif. Tapi apa sebenarnya yang membedakan shell login dari shell non-login?
Bisakah Anda memberikan contoh penggunaan shell interaktif non-login ?
Saya pikir pertanyaannya lebih baik dijabarkan sebagai " Mengapa kita harus peduli untuk membedakan shell login dan non-login?" Banyak tempat di web sudah memberi tahu kami apa perbedaannya, dalam hal apa file startup masing-masing dibaca; tetapi tidak satupun dari mereka yang menjawab "mengapa" dengan cara yang memuaskan dan meyakinkan. Contoh kasus penggunaan di mana Anda pasti tidak ingin satu atau perilaku lain akan bagus.
Shell login adalah proses pertama yang dijalankan di bawah ID pengguna Anda ketika Anda masuk untuk sesi interaktif. Proses login memberitahu shell untuk berperilaku sebagai shell login dengan konvensi: lewat argumen 0, yang biasanya nama shell dieksekusi, dengan -karakter yang diawali (misalnya -bashpadahal biasanya bash. Shell login biasanya membaca file yang tidak hal-hal seperti pengaturan variabel lingkungan: /etc/profiledan ~/.profileuntuk shell Bourne tradisional, ~/.bash_profiletambahan untuk bash † , /etc/zprofiledan ~/.zprofileuntuk zsh † , /etc/csh.logindan ~/.loginuntuk csh, dll.
Ketika Anda masuk pada konsol teks, atau melalui SSH, atau dengan su -, Anda mendapatkan shell login interaktif . Ketika Anda masuk dalam mode grafis (pada manajer tampilan X ), Anda tidak mendapatkan shell login, sebaliknya Anda mendapatkan manajer sesi atau manajer jendela.
Jarang menjalankan shell login non-interaktif , tetapi beberapa pengaturan X melakukannya ketika Anda masuk dengan manajer tampilan, sehingga dapat mengatur untuk membaca file profil. Pengaturan lain (ini tergantung pada distribusi dan manajer tampilan) membaca /etc/profiledan ~/.profilesecara eksplisit, atau tidak membacanya. Cara lain untuk mendapatkan shell login non-interaktif adalah untuk login jarak jauh dengan perintah yang melewati input standar yang bukan terminal, misalnya ssh example.com <my-script-which-is-stored-locally(sebagai lawan dari ssh example.com my-script-which-is-on-the-remote-machine, yang menjalankan shell non-interaktif, non-login).
Ketika Anda memulai shell di terminal dalam sesi yang ada (layar, terminal X, buffer terminal Emacs, shell di dalam yang lain, dll), Anda mendapatkan shell interaktif, non-login . Shell itu mungkin membaca file konfigurasi shell ( ~/.bashrcuntuk bash dipanggil sebagai bash, /etc/zshrcdan ~/.zshrcuntuk zsh, /etc/csh.cshrcdan ~/.cshrcuntuk csh, file yang ditunjukkan oleh ENVvariabel untuk shell yang sesuai dengan POSIX / XSI seperti dash, ksh, dan bash ketika dipanggil sebagai sh, $ENVjika diatur dan ~/.mkshrcuntuk mksh, dll.).
Ketika shell menjalankan skrip atau perintah yang diteruskan pada baris perintahnya, itu adalah shell non-interaktif, non-login . Kerang semacam itu berjalan sepanjang waktu: sangat umum bahwa ketika suatu program memanggil program lain, ia benar-benar menjalankan sebuah skrip kecil dalam sebuah shell untuk memanggil program lain itu. Beberapa shell membaca file startup dalam hal ini (bash menjalankan file yang ditunjukkan oleh BASH_ENVvariabel, zsh menjalankan /etc/zshenvdan ~/.zshenv), tetapi ini berisiko: shell dapat dipanggil dalam segala macam konteks, dan hampir tidak ada apa pun yang dapat Anda lakukan yang mungkin tidak menghancurkan sesuatu.
† Saya menyederhanakan sedikit, lihat manual untuk detail berdarah.
Bisakah Anda memberi contoh cara menjalankan bashsebagai shell login non-interaktif?
Piotr Dobrogost
13
@PiotrDobrogostecho $- | bash -lx
Gilles
1
Saya tidak tahu apakah ini benar secara umum, tetapi saya ingin mencatat bahwa ketika saya membuka terminal baru (di osx menggunakan pengaturan default), saya mendapatkan shell login meskipun saya tidak pernah mengetikkan nama pengguna atau kata sandi saya.
Kevin Wheeler
4
@KevinWheeler Pada OSX, secara default, aplikasi Terminal menjalankan shell login. (Seperti yang saya jelaskan, program yang menjalankan shell memutuskan apakah shell bertindak sebagai shell login.) Itu bukan cara normal untuk melakukan sesuatu.
Gilles
2
@IAmJulianAcosta If FOOadalah variabel lingkungan (yaitu .profileberisi export FOO=something) maka itu tersedia untuk semua subproses, termasuk foo.sh. Jika Anda mengubah .profileke export FOO=something_elsekemudian ./foo.shmasih akan mencetak somethingsampai waktu berikutnya Anda login.
Gilles
48
Untuk mengetahui apakah Anda berada di shell login:
prompt> echo $0-bash # "-" is the first character. Therefore, this is a login shell.
prompt> echo $0
bash # "-" is NOT the first character. This is NOT a login shell.
Pentingnya menggunakan shell login adalah bahwa semua pengaturan di /home/user/.bash_profileakan dieksekusi. Berikut ini sedikit informasi lebih lanjut jika Anda tertarik (dari man bash)
"Ketika bash dipanggil sebagai shell login interaktif, atau sebagai shell non-interaktif dengan opsi --login, ia pertama kali membaca dan mengeksekusi perintah dari file / etc / profile, jika file itu ada. Setelah membaca file itu, itu mencari ~/.bash_profile,
~/.bash_logindan ~/.profile, agar, dan membaca dan mengeksekusi perintah dari yang pertama yang ada dan dapat dibaca. opsi --noprofile dapat digunakan ketika shell dimulai untuk menghambat perilaku ini."
Di shell login argv[0][0] == '-',. Inilah yang diketahui sebagai shell login.
Dan kemudian dalam beberapa situasi berperilaku berbeda tergantung pada status "login shell" -nya. Misalnya shell, yang bukan shell login, tidak akan menjalankan perintah "logout".
Menurut man bash, dengan penekanan ditambahkan, "Shell login adalah karakter shell pertama yang argumennya nol adalah -, atau yang dimulai dengan opsi --login. "
Wildcard
18
Shell yang dimulai di terminal baru dalam GUI akan menjadi shell non-login interaktif. Itu akan sumber. Bashrc Anda, tetapi bukan. Profil Anda, misalnya.
ssh ubuntu@34.247.105.87Welcome to Ubuntu16.04.5 LTS (GNU/Linux4.4.0-1083-aws x86_64)
ubuntu@ip-172-31-0-70:~$ THIS_SHELL_INTERACTIVE_TYPE='non-interactive';
ubuntu@ip-172-31-0-70:~$ THIS_SHELL_LOGIN_TYPE='non-login';
ubuntu@ip-172-31-0-70:~$ if tty -s;then THIS_SHELL_INTERACTIVE_TYPE='interactive';fi;
ubuntu@ip-172-31-0-70:~$ if echo $0 | grep -e ^\- 2>&1>/dev/null;then THIS_SHELL_LOGIN_TYPE='login';fi;
ubuntu@ip-172-31-0-70:~$ echo "$THIS_SHELL_INTERACTIVE_TYPE/$THIS_SHELL_LOGIN_TYPE"
interactive/login
Menjalankan skrip atau mengeksekusi secara eksplisit melalui shell baru
ubuntu@ip-172-31-0-70:~$ bash -c 'THIS_SHELL_INTERACTIVE_TYPE='non-interactive'; THIS_SHELL_LOGIN_TYPE='non-login'; if tty -s; then THIS_SHELL_INTERACTIVE_TYPE='interactive'; fi; if echo $0 | grep -e ^\- 2>&1>/dev/null; then THIS_SHELL_LOGIN_TYPE='login'; fi;
echo "$THIS_SHELL_INTERACTIVE_TYPE/$THIS_SHELL_LOGIN_TYPE"'
interactive/non-login
Menjalankan skrip lokal dari jarak jauh
ssh ubuntu@34.247.105.87< checkmy.shPseudo-terminal will not be allocated because stdin is not a terminal.Welcome to Ubuntu16.04.5 LTS (GNU/Linux4.4.0-1083-aws x86_64)
non-interactive/login
Menjalankan perintah di atas ssh dari jarak jauh
ssh ubuntu@34.247.105.87'THIS_SHELL_INTERACTIVE_TYPE='non-interactive'; THIS_SHELL_LOGIN_TYPE='non-login'; if tty -s; then THIS_SHELL_INTERACTIVE_TYPE='interactive'; fi; if echo $0 | grep -e ^\- 2>&1>/dev/null; then THIS_SHELL_LOGIN_TYPE='login'; fi; echo "$THIS_SHELL_INTERACTIVE_TYPE/$THIS_SHELL_LOGIN_TYPE"'
non-interactive/non-login
Menjalankan perintah di atas ssh dari jarak jauh dengan -tsakelar
Anda dapat secara eksplisit meminta shell interaktif ketika Anda ingin menjalankan perintah dari jarak jauh melalui ssh dengan menggunakan -tsakelar.
ssh ubuntu@34.247.105.87-t 'THIS_SHELL_INTERACTIVE_TYPE='non-interactive'; THIS_SHELL_LOGIN_TYPE='non-login'; if tty -s; then THIS_SHELL_INTERACTIVE_TYPE='interactive'; fi; if echo $0 | grep -e ^\- 2>&1>/dev/null; then THIS_SHELL_LOGIN_TYPE='login'; fi; echo "$THIS_SHELL_INTERACTIVE_TYPE/$THIS_SHELL_LOGIN_TYPE"'
interactive/non-login
Catatan: Pada topik mengapa menjalankan perintah dari jarak jauh bukan login shellinfo lebih lanjut di sini .
Jawaban:
Shell login adalah proses pertama yang dijalankan di bawah ID pengguna Anda ketika Anda masuk untuk sesi interaktif. Proses login memberitahu shell untuk berperilaku sebagai shell login dengan konvensi: lewat argumen 0, yang biasanya nama shell dieksekusi, dengan
-
karakter yang diawali (misalnya-bash
padahal biasanyabash
. Shell login biasanya membaca file yang tidak hal-hal seperti pengaturan variabel lingkungan:/etc/profile
dan~/.profile
untuk shell Bourne tradisional,~/.bash_profile
tambahan untuk bash † ,/etc/zprofile
dan~/.zprofile
untuk zsh † ,/etc/csh.login
dan~/.login
untuk csh, dll.Ketika Anda masuk pada konsol teks, atau melalui SSH, atau dengan
su -
, Anda mendapatkan shell login interaktif . Ketika Anda masuk dalam mode grafis (pada manajer tampilan X ), Anda tidak mendapatkan shell login, sebaliknya Anda mendapatkan manajer sesi atau manajer jendela.Jarang menjalankan shell login non-interaktif , tetapi beberapa pengaturan X melakukannya ketika Anda masuk dengan manajer tampilan, sehingga dapat mengatur untuk membaca file profil. Pengaturan lain (ini tergantung pada distribusi dan manajer tampilan) membaca
/etc/profile
dan~/.profile
secara eksplisit, atau tidak membacanya. Cara lain untuk mendapatkan shell login non-interaktif adalah untuk login jarak jauh dengan perintah yang melewati input standar yang bukan terminal, misalnyassh example.com <my-script-which-is-stored-locally
(sebagai lawan darissh example.com my-script-which-is-on-the-remote-machine
, yang menjalankan shell non-interaktif, non-login).Ketika Anda memulai shell di terminal dalam sesi yang ada (layar, terminal X, buffer terminal Emacs, shell di dalam yang lain, dll), Anda mendapatkan shell interaktif, non-login . Shell itu mungkin membaca file konfigurasi shell (
~/.bashrc
untuk bash dipanggil sebagaibash
,/etc/zshrc
dan~/.zshrc
untuk zsh,/etc/csh.cshrc
dan~/.cshrc
untuk csh, file yang ditunjukkan olehENV
variabel untuk shell yang sesuai dengan POSIX / XSI seperti dash, ksh, dan bash ketika dipanggil sebagaish
,$ENV
jika diatur dan~/.mkshrc
untuk mksh, dll.).Ketika shell menjalankan skrip atau perintah yang diteruskan pada baris perintahnya, itu adalah shell non-interaktif, non-login . Kerang semacam itu berjalan sepanjang waktu: sangat umum bahwa ketika suatu program memanggil program lain, ia benar-benar menjalankan sebuah skrip kecil dalam sebuah shell untuk memanggil program lain itu. Beberapa shell membaca file startup dalam hal ini (bash menjalankan file yang ditunjukkan oleh
BASH_ENV
variabel, zsh menjalankan/etc/zshenv
dan~/.zshenv
), tetapi ini berisiko: shell dapat dipanggil dalam segala macam konteks, dan hampir tidak ada apa pun yang dapat Anda lakukan yang mungkin tidak menghancurkan sesuatu.† Saya menyederhanakan sedikit, lihat manual untuk detail berdarah.
sumber
bash
sebagai shell login non-interaktif?echo $- | bash -lx
FOO
adalah variabel lingkungan (yaitu.profile
berisiexport FOO=something
) maka itu tersedia untuk semua subproses, termasukfoo.sh
. Jika Anda mengubah.profile
keexport FOO=something_else
kemudian./foo.sh
masih akan mencetaksomething
sampai waktu berikutnya Anda login.Untuk mengetahui apakah Anda berada di shell login:
Di Bash, Anda juga dapat menggunakan
shopt login_shell
:(atau
on
di shell login).Informasi dapat ditemukan di
man bash
(mencari Doa). Berikut ini kutipannya:Anda bisa mengujinya sendiri. Kapan pun Anda menggunakan SSH, Anda menggunakan shell login. Sebagai contoh:
Pentingnya menggunakan shell login adalah bahwa semua pengaturan di
/home/user/.bash_profile
akan dieksekusi. Berikut ini sedikit informasi lebih lanjut jika Anda tertarik (dariman bash
)sumber
Di shell login
argv[0][0] == '-'
,. Inilah yang diketahui sebagai shell login.Dan kemudian dalam beberapa situasi berperilaku berbeda tergantung pada status "login shell" -nya. Misalnya shell, yang bukan shell login, tidak akan menjalankan perintah "logout".
sumber
man bash
, dengan penekanan ditambahkan, "Shell login adalah karakter shell pertama yang argumennya nol adalah -, atau yang dimulai dengan opsi --login. "Shell yang dimulai di terminal baru dalam GUI akan menjadi shell non-login interaktif. Itu akan sumber. Bashrc Anda, tetapi bukan. Profil Anda, misalnya.
sumber
Saya akan menguraikan jawaban hebat dari Gilles, dikombinasikan dengan metode Timothy untuk memeriksa tipe shell login.
Jika Anda suka melihat hal-hal sendiri, coba cuplikan dan skenario di bawah ini.
Memeriksa apakah shell (non-) interaktif
Memeriksa apakah shell (non-) login
Jika output
echo $0
dimulai dengan-
, itu shell login (echo $0
contoh output:)-bash
. Kalau tidak, ini shell non-login (echo $0
contoh output:)bash
.Mari kita gabungkan keduanya di atas untuk mendapatkan kedua informasi sekaligus:
Skenario:
Sesi SSH khas tanpa opsi khusus
Menjalankan skrip atau mengeksekusi secara eksplisit melalui shell baru
Menjalankan skrip lokal dari jarak jauh
Menjalankan perintah di atas ssh dari jarak jauh
Menjalankan perintah di atas ssh dari jarak jauh dengan
-t
sakelarAnda dapat secara eksplisit meminta shell interaktif ketika Anda ingin menjalankan perintah dari jarak jauh melalui ssh dengan menggunakan
-t
sakelar.Catatan: Pada topik mengapa menjalankan perintah dari jarak jauh bukan
login shell
info lebih lanjut di sini .sumber