TL; DR :
- Trường hợp đăng nhập được xác định? Trong
/etc/passwd
.
- Là
sudo su
/ sudo su -
/ sudo -i
/ sudo -s
giố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ì
$SHELL
là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 shopt
là đặc thù của bash. Chẳng hạn, tôi là mksh
người dùng shell, và nó không có shopt
, giống như ksh
khô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 shopt
báo cáo login_shell on
cho tùy chọn này. Hãy nghĩ về điều này như thể sudo -i
buộ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 -s
chỉ đọ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 $SHELL
hoặc sudo mksh
hoặ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à mksh
ngườ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 -s
nhảy từ vỏ bash
củ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ì bash
nó 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 su
và 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_shell
không có liên quan đến $SHELL
bấ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à .bashrc
vì 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 .bashrc
tệp. Vì vậy, chúng tôi có thể kiểm tra echo
xem 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 echo
cho 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
.
.profile
hoặ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/passwd
hoặc tương đương.$SHELL
chứa cái sau,shopt
kế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.