TL; DR :
- Trường hợp đăng nhập được xác định? Trong
/etc/passwd.
- Là
sudo su/ sudo su -/ sudo -i/ sudo -sgiống nhau? Không, tất cả chúng sinh ra một cái vỏ nhưng khác nhau và trong các bối cảnh khác nhau.
- Không gì
$SHELLlàm gì? Chỉ cần nói với shell mặc định của bạn, giống như trong /etc/passwd.
Trả lời thực tế :
Trước hết, điều quan trọng cần đề cập shoptlà đặc thù của bash. Chẳng hạn, tôi là mkshngười dùng shell, và nó không có shopt, giống như kshkhông.
Tiếp theo, chính xác những gì login_shellđược cho là đại diện? Từ man bash:
login_shell
Shell đặt tùy chọn này nếu nó được bắt đầu như một shell đăng nhập
Đó là điểm mấu chốt. sudo -i, như bạn đã biết từ câu trả lời trước mà bạn đã đọc, được cho là mô phỏng đăng nhập ban đầu. Đó là lý do tại sao shoptbáo cáo login_shell on cho tùy chọn này. Hãy nghĩ về điều này như thể sudo -ibuộc shell phải đi qua các tệp được cho là chỉ xuất hiện trong quá trình đăng nhập (không được lấy nguồn từ các shell tương tác).
Trong các trường hợp khác, bạn đã chạy một thể hiện của shell, vì vậy nó không thể là shell đăng nhập ở vị trí đầu tiên và mục đích của các tùy chọn là khác nhau. sudo -schỉ đọc $SHELL(có nghĩa là đại diện cho vỏ mặc định của bạn như được đặt trong /etc/passwd) và chạy nó với đặc quyền gốc. Đây là tương đương với làm sudo $SHELLhoặc sudo mkshhoặc sudo bash(tùy bạn tình cờ sử dụng).
Hãy nhớ rằng tôi đã đề cập rằng tôi là mkshngười dùng? Hãy xem này:
$ 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
Những gì bạn thấy là sudo -snhảy từ vỏ bashcủa tôi mksh, với dấu nhắc đặc trưng mà tôi đã đặt cho nó. Và tất nhiên, vì nó không phải là một hành động đăng nhập, vì bashnó sẽ báo cáo rằng shell được sinh ra như là một thể hiện shell không đăng nhập. Tuy nhiên, trong trường hợp của tôi, bạn thấy rằng $-không có một chữ cái nào lở đó, nó sẽ ở đó nếu đó là một ví dụ shell đăng nhập.
Cuối cùng, ý tưởng tương tự áp dụng cho sudo suvà sudo su -. Sau đó, một trường hợp sinh ra vỏ đăng nhập (nghĩa là các tệp cụ thể được yêu cầu để đăng nhập sẽ chạy) và trước đây chỉ sinh ra các vỏ tương tác (nghĩa là các tệp đăng nhập không chạy).
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
Vì vậy, về mặt kỹ thuật, shopt login_shellkhông có liên quan đến $SHELLbất cứ điều gì. Hãy nghĩ về nó theo cách này: mục đích của nó là chỉ ra cách bash chạy. $SHELLđược cho là chỉ phản ánh những gì bạn đã chỉ định /etc/passwd.
Đối với sự khác biệt giữa shell đăng nhập và shell không đăng nhập, nó đã được giải thích bởi Gilles rất được tôn trọng trên unix.stackexchange.com trong câu trả lời này .
Thêm niềm vui
Đây là một cái gì đó thú vị mà bạn có thể thử. Như bạn có thể đã biết, một vỏ đăng nhập sẽ chạy .profile(và .bashrcvì Ubuntu .profile được cấu hình để làm như vậy ), nhưng địa ngục không đăng nhập sẽ chỉ chạy .bashrctệp. Vì vậy, chúng tôi có thể kiểm tra echoxem lệnh nào trong số các lệnh này chạy shell đăng nhập và lệnh nào không, và chúng tôi mong đợi hai dòng echocho shell đăng nhập và chỉ một dòng cho không đăng nhập.
$ 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:~#
Một cách thích hợp, những người có hai dòng đầu ra sẽ được login_shellđặt thành on.
.profilehoặc tương đương) và 2. Đó là shell được cho là bắt đầu khi đăng nhập cho một người dùng, như được định nghĩa trong/etc/passwdhoặc tương đương.$SHELLchứa cái sau,shoptkết quả đầu ra của bạn đối phó với cái trước. Thông thường, khi shell trong (2) được bắt đầu khi đăng nhập, nó được bắt đầu theo cách cụ thể cần thiết cho (1), do đó kết hợp các ý nghĩa.