Di mana shell login didefinisikan?

16

Saya membaca perbedaan antara sudo -i/-s sini . Setelah menggunakan perintah shopt, dicatat bahwa semua ( sudo su/sudo -i/sudo -s) $SHELLmemberikan hasil yang sama, tetapi shopthasil perintah berbeda.

Jadi, bagaimana cara mendefinisikan shell login dan non login?

Dari mana shoptmendapatkan hasilnya?

Mengapa itu tidak terkait $SHELL?

sudo su

givinv@87-109:~$ sudo su
root@87-109:/home/givinv# 
root@87-109:/home/givinv# 
root@87-109:/home/givinv# shopt -q login_shell && echo 'Login shell' || echo 'No login shell'
No login shell
root@87-109:/home/givinv# echo $SHELL
/bin/bash
root@87-109:/home/givinv# 
root@87-109:/home/givinv# exit
givinv@87-109:~$ 

sudo -i

givinv@87-109:~$ sudo -i
root@87-109:~# 
root@87-109:~# shopt -q login_shell && echo 'Login shell' || echo 'No login shell'
Login shell
root@87-109:~# echo $SHELL
/bin/bash
root@87-109:~# 

sudo -s

root@87-109:~# sudo -s
root@87-109:~# shopt -q login_shell && echo 'Login shell' || echo 'No login shell'
No login shell
root@87-109:~# echo $SHELL
/bin/bash
root@87-109:~# 
prado
sumber
7
Satu masalah adalah bahwa "shell login" memiliki dua arti: 1. Ini adalah contoh dari shell yang dimulai dengan cara tertentu yang melakukan hal-hal tertentu (seperti membaca .profileatau setara), dan 2. Shell yang seharusnya dimulai saat login untuk sebuah pengguna, sebagaimana didefinisikan dalam /etc/passwdatau setara. $SHELLberisi yang terakhir, shoptoutput Anda berurusan dengan yang pertama. Biasanya, ketika shell dalam (2) dimulai pada saat login, itu dimulai dengan cara khusus yang diperlukan untuk (1), maka dari itu pengubahan makna.
muru
1
Penjelasan @uru adalah yang bagus. misalnya jika Anda SSH ke komputer Anda dari mesin jarak jauh. / usr / sbin / sshd pada sistem Anda akan menggunakan shell yang didefinisikan oleh $SHELL(dan menghubungkannya ke terminal semu) yang pada gilirannya didefinisikan dalam entri / etc / passwd Anda. shell ini adalah shell login dan dapat diuji dengan if [[ -o login ]]; then echo "I am a login shell"; fi. menjadi shell login akan melakukan tugas-tugas yang sesuai dengan sesi baru. mis. sumber ~/.zprofileatau yang serupa yang mungkin akan mengatur variabel lingkungan dan kode shell khusus apa pun yang mungkin ingin Anda jalankan saat ini
the_velour_fog

Jawaban:

17

TL; DR :

  • Di mana shell login didefinisikan? Dalam /etc/passwd.
  • Apakah sudo su/ sudo su -/ sudo -i/ sudo -ssama? Tidak, mereka semua menghasilkan cangkang tetapi berbeda dan dalam konteks yang berbeda.
  • Apa yang $SHELLharus dilakukan Katakan saja shell default Anda, sama seperti di /etc/passwd.

Jawaban Aktual :

Pertama-tama, penting untuk menyebutkan bahwa shoptitu spesifik-bash. Sebagai contoh, saya mkshpengguna shell, dan tidak memiliki shopt, sama seperti kshtidak.

Selanjutnya, apa sebenarnya login_shellyang harus diwakili? Dari man bash:

login_shell

Shell menetapkan opsi ini jika dimulai sebagai shell login

Itulah poin kuncinya. sudo -i, seperti yang sudah Anda ketahui dari jawaban sebelumnya yang Anda baca, seharusnya mensimulasikan login awal. Itu sebabnya shoptlaporan login_shell on untuk opsi ini. Pikirkan ini seolah sudo -imemaksa shell untuk pergi melalui file yang seharusnya hanya muncul selama proses login (yang tidak bersumber dari shell interaktif).

Dalam kasus lain, Anda sudah menjalankan instance dari shell, jadi itu tidak bisa menjadi shell login di tempat pertama, dan tujuan dari opsi berbeda. sudo -shanya membaca $SHELL(yang dimaksudkan untuk mewakili shell default Anda sebagaimana diatur dalam /etc/passwd) variabel dan menjalankannya dengan hak akses root. Ini sama dengan melakukan sudo $SHELLatau sudo mkshatau sudo bash(mana pun yang Anda gunakan).

Ingat saya sebutkan bahwa saya mkshpengguna? Lihatlah ini:

$ bash --posix
bash-4.3$ sudo -s
[sudo] password for xieerqi: 

DIR:/xieerqi|01:53|skolodya@ubuntu:
$ id 
uid=0(root) gid=0(root) groups=0(root)

DIR:/xieerqi|01:53|skolodya@ubuntu:
$ echo $-
imsU

Apa yang Anda lihat adalah yang sudo -smelompat dari shell bashsaya mksh, dengan prompt karakteristik yang saya tetapkan untuk itu. Dan tentu saja, karena ini bukan tindakan masuk, karena bashakan melaporkan bahwa shell muncul sebagai contoh shell non-login. Dalam kasus saya, Anda melihat bahwa $-tidak lada surat di sana, yang akan ada di sana jika itu adalah contoh shell login.

Akhirnya, ide yang sama berlaku untuk sudo sudan sudo su -. Kemudian satu spawns instance shell login (yaitu, file spesifik yang diperlukan untuk login akan berjalan) dan yang pertama hanya memunculkan shell interaktif (yaitu, file login tidak berjalan).

bash-4.3$ sudo su
[sudo] password for xieerqi: 
root@eagle:/home/xieerqi# shopt login_shell
login_shell     off
root@eagle:/home/xieerqi# exit
bash-4.3$ sudo su -
[sudo] password for xieerqi: 
$ shopt login_shell
login_shell     on

Jadi secara teknis, shopt login_shelltidak ada hubungannya dengan $SHELLapa pun. Pikirkan seperti ini: tujuannya adalah untuk menunjukkan bagaimana bash berjalan. $SHELLseharusnya hanya mencerminkan apa yang telah Anda tetapkan /etc/passwd.

Adapun perbedaan antara shell login dan shell non-login, telah dijelaskan oleh Gilles yang sangat dihormati di unix.stackexchange.com dalam jawaban ini .


Menyenangkan tambahan

Inilah sesuatu yang menyenangkan yang bisa Anda coba. Seperti yang mungkin sudah Anda ketahui, shell login akan berjalan .profile(dan .bashrckarena Ubuntu .profile dikonfigurasikan untuk melakukannya ), tetapi neraka non-login hanya akan menjalankan .bashrcfile. Jadi kita dapat menguji dengan echoperintah mana yang menjalankan shell login dan mana yang tidak, dan kami mengharapkan dua baris echountuk shell login dan hanya satu untuk non-login.

$ echo "echo 'hi,i am .profile'"  >> .profile
$ echo "echo 'hi, i am .bashrc'" >> .bashrc
$ sudo -i
hi, i am .bashrc
hi,i am .profile
$ sudo su
hi, i am .bashrc
root@eagle:~# sudo su -
hi, i am .bashrc
hi,i am .profile
$ sudo -s
hi, i am .bashrc
root@eagle:~# 

Cukup tepat, mereka yang memiliki dua jalur output akan login_shelldiatur ke on.

Sergiy Kolodyazhnyy
sumber
@Serg dan @Zanna terima kasih. Sekarang tentang $SHELLdan login_shell/non-login_shelldiklarifikasi. Tapi dari mana shoptmendapatkan detail? Apakah itu dari echo $0?
Prado
1
@prado Saya akan mengatakan ya, karena karakter pertama $0digunakan untuk menentukan apakah shell adalah shell login, jadi jika shoptakan memeriksa variabel itu - tentu, itu bisa diterima. Namun, mungkin ada lebih dari yang terlihat. shoptmungkin Untuk pertanyaan ini, saya tidak memiliki jawaban yang sulit, karena saya tidak terbiasa dengan kode sumber bash dengan baik.
Sergiy Kolodyazhnyy
@prado Bash dapat dimulai sebagai shell login dengan karakter pertama sebesar $ 0 -, atau dengan menggunakan -lopsi.
muru
@prado, Anda dapat membaca tentang permintaan dan opsi bash di halaman manual. misalnya bagian SHELL BUILTIN COMMAND mengatakan login_shell The shell sets this option if it is started as a login shell (see INVOCATION above). The value may not be changed.agar shopt login_shelltampaknya menjadi satu arah, Anda dapat mencari tahu - secara terprogram cara mengetahui bagaimana hal itu dimulai. cara lain adalah[[ -o login ]]
the_velour_fog
11

Ketika @Serg menjelaskan dalam jawaban ini tentang cara memberi tahu shell apa yang Anda jalankan , SHELLvariabelnya hanyalah shell default pengguna saat ini seperti yang dibaca dari /etc/passwd:

$ grep zanna /etc/passwd
zanna:x:1000:1000:Zanna,,,:/home/zanna:/bin/bash

jadi jika saya echo $SHELLakan selalu kembali /bin/bash:

$ zsh
% echo $SHELL
/bin/bash

Apakah atau tidak shell adalah shell login, adalah sh ell opt ion ditentukan pada saat shell dimulai. Program shell menyimpan informasi ini bersama dengan semua pengaturan dan variabel lainnya. The shoptperintah menyediakan cara untuk melihat informasi ini dan, jika mungkin untuk opsi tersebut, untuk mengatur atau unset itu (ini bukan kasus untuk login_shellyang, tentu saja, tergantung pada proses yang digunakan untuk memulai shell)

Opsi sudoprogram menentukan bagaimana berbagai jenis shell root akan dimulai:

masukkan deskripsi gambar di sini

Zanna
sumber
1
Penjelasan yang bagus. Saya pikir Anda telah menjelaskan apa shoptdan login_shellseharusnya mewakili jauh lebih baik dari jawaban saya.
Sergiy Kolodyazhnyy
@Serg, terima kasih :) Saya pikir penjelasan Anda lebih menyeluruh :)
Zanna
3

man bash:

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

man login:

Nilai untuk $HOME, $SHELL[...] diatur sesuai dengan bidang yang sesuai dalam entri kata sandi.

Pendeknya:

  • Shell adalah shell login jika dipanggil sebagai shell login.
  • Variabel lingkungan $SHELLdiatur oleh loginatau oleh program pemohon, misalnya su. Shell itu sendiri tidak mengaturnya.
  • shopt menunjukkan opsi shell yang sedang berlaku.
AlexP
sumber