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 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 ?
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 biasanya bash
. 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, 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 ( ~/.bashrc
untuk bash dipanggil sebagai bash
, /etc/zshrc
dan ~/.zshrc
untuk zsh, /etc/csh.cshrc
dan ~/.cshrc
untuk csh, file yang ditunjukkan oleh ENV
variabel untuk shell yang sesuai dengan POSIX / XSI seperti dash, ksh, dan bash ketika dipanggil sebagai sh
, $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.
bash
sebagai shell login non-interaktif?
echo $- | bash -lx
FOO
adalah variabel lingkungan (yaitu .profile
berisi export FOO=something
) maka itu tersedia untuk semua subproses, termasuk foo.sh
. Jika Anda mengubah .profile
ke export FOO=something_else
kemudian ./foo.sh
masih akan mencetak something
sampai waktu berikutnya Anda login.
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 on
di 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_profile
akan 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_login
dan~/.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".
man bash
, dengan penekanan ditambahkan, "Shell login adalah karakter shell pertama yang argumennya nol adalah -, atau yang dimulai dengan opsi --login. "
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 $0
dimulai dengan -
, itu shell login ( echo $0
contoh output:) -bash
. Kalau tidak, ini shell non-login ( echo $0
contoh 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"
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
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
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
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
-t
sakelarAnda dapat secara eksplisit meminta shell interaktif ketika Anda ingin menjalankan perintah dari jarak jauh melalui ssh dengan menggunakan -t
sakelar.
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 shell
info lebih lanjut di sini .