Perbedaan antara Shell Login dan Shell Non-Login?


318

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 ?


45
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.
Kal

2
@ Kal Ini harus menjadi pertanyaan yang berbeda, karena tidak ada jawaban di sini yang sebenarnya mencakup itu. Sunting: Sebenarnya, ini dia: MENGAPA shell login lebih dari shell non-login ? .
Skippy le Grand Gourou

Jawaban:


304

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.


2
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.

Di Bash, Anda juga dapat menggunakan shopt login_shell:

prompt> shopt login_shell
login_shell     off

(atau ondi shell login).

Informasi dapat ditemukan di man bash(mencari Doa). Berikut ini kutipannya:

Shell login adalah karakter yang argumen pertama nol adalah a -, atau yang dimulai dengan opsi --login.

Anda bisa mengujinya sendiri. Kapan pun Anda menggunakan SSH, Anda menggunakan shell login. Sebagai contoh:

prompt> ssh user@localhost
user@localhost's password:
prompt> echo $0
-bash

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."


23

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".


4
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.


4

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

if tty -s; then echo 'This is interactive shell.'; else echo 'This is non-interactive shell.'; fi

Memeriksa apakah shell (non-) login

Jika output echo $0dimulai dengan -, itu shell login ( echo $0contoh output:) -bash. Kalau tidak, ini shell non-login ( echo $0contoh output:) bash.

if echo $0 | grep -e ^\- 2>&1>/dev/null; then echo "This is login shell."; else echo "This is non-login shell."; fi;

Mari kita gabungkan keduanya di atas untuk mendapatkan kedua informasi sekaligus:

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"

Skenario:

Sesi SSH khas tanpa opsi khusus

ssh ubuntu@34.247.105.87
Welcome to Ubuntu 16.04.5 LTS (GNU/Linux 4.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.sh
Pseudo-terminal will not be allocated because stdin is not a terminal.
Welcome to Ubuntu 16.04.5 LTS (GNU/Linux 4.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 .

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.