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 -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.
bashsebagai shell login non-interaktif?
echo $- | bash -lx
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.
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."
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 $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"
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
-tsakelarAnda 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 .