Tôi hiểu sự khác biệt cơ bản giữa vỏ tương tác và vỏ không tương tác. Nhưng chính xác những gì phân biệt một vỏ đăng nhập từ một vỏ không đăng nhập?
Bạn có thể đưa ra ví dụ cho việc sử dụng shell tương tác không đăng nhập không?
Tôi hiểu sự khác biệt cơ bản giữa vỏ tương tác và vỏ không tương tác. Nhưng chính xác những gì phân biệt một vỏ đăng nhập từ một vỏ không đăng nhập?
Bạn có thể đưa ra ví dụ cho việc sử dụng shell tương tác không đăng nhập không?
Câu trả lời:
Shell đăng nhập là quá trình đầu tiên thực thi theo ID người dùng của bạn khi bạn đăng nhập vào một phiên tương tác. Quá trình đăng nhập yêu cầu shell hoạt động như một shell đăng nhập với quy ước: truyền đối số 0, thường là tên của shell có thể thực thi được, với một -
ký tự được đặt trước (ví dụ như -bash
thông thường bash
. Shell đăng nhập thường đọc một tệp những thứ như thiết lập các biến môi trường: /etc/profile
và ~/.profile
cho truyền thống Bourne vỏ, ~/.bash_profile
bổ sung cho bash † , /etc/zprofile
và ~/.zprofile
cho zsh † , /etc/csh.login
và ~/.login
cho csh vv
Khi bạn đăng nhập trên bảng điều khiển văn bản hoặc thông qua SSH hoặc với su -
, bạn sẽ nhận được vỏ đăng nhập tương tác . Khi bạn đăng nhập ở chế độ đồ họa (trên trình quản lý hiển thị X ), bạn không nhận được vỏ đăng nhập, thay vào đó bạn có trình quản lý phiên hoặc trình quản lý cửa sổ.
Rất hiếm khi chạy shell đăng nhập không tương tác , nhưng một số cài đặt X thực hiện điều đó khi bạn đăng nhập bằng trình quản lý hiển thị, để sắp xếp đọc các tệp hồ sơ. Các cài đặt khác (điều này phụ thuộc vào bản phân phối và trình quản lý hiển thị) đọc /etc/profile
và đọc ~/.profile
rõ ràng hoặc không đọc chúng. Một cách khác để có được vỏ đăng nhập không tương tác là đăng nhập từ xa bằng lệnh được truyền qua đầu vào tiêu chuẩn không phải là thiết bị đầu cuối, ví dụ ssh example.com <my-script-which-is-stored-locally
(trái ngược với ssh example.com my-script-which-is-on-the-remote-machine
, chạy vỏ không đăng nhập, không tương tác).
Khi bạn khởi động một shell trong một thiết bị đầu cuối trong một phiên hiện có (màn hình, thiết bị đầu cuối X, bộ đệm thiết bị đầu cuối Emacs, một vỏ bên trong một thiết bị khác, v.v.), bạn sẽ nhận được một vỏ tương tác, không đăng nhập . Vỏ có thể đọc một tập tin cấu hình vỏ ( ~/.bashrc
cho bash gọi là bash
, /etc/zshrc
và ~/.zshrc
cho zsh, /etc/csh.cshrc
và ~/.cshrc
cho csh, các tập tin được chỉ ra bởi ENV
biến cho vỏ POSIX / XSI tuân thủ như dấu gạch ngang, ksh và bash khi gọi như sh
, $ENV
nếu thiết lập và ~/.mkshrc
cho mksh, v.v.).
Khi shell chạy tập lệnh hoặc lệnh được truyền trên dòng lệnh của nó, đó là shell không tương tác, không đăng nhập . Các shell như vậy chạy mọi lúc: rất phổ biến là khi một chương trình gọi một chương trình khác, nó thực sự chạy một đoạn script nhỏ trong một shell để gọi chương trình khác đó. Một số shell đọc tệp khởi động trong trường hợp này (bash chạy tệp được chỉ định bởi BASH_ENV
biến, zsh chạy /etc/zshenv
và ~/.zshenv
), nhưng điều này rất nguy hiểm: shell có thể được gọi trong tất cả các loại ngữ cảnh và hầu như không có gì bạn có thể làm mà không thể phá hủy một số thứ.
† Tôi đang đơn giản hóa một chút, xem hướng dẫn cho các chi tiết đẫm máu.
bash
như một vỏ đăng nhập không tương tác?
echo $- | bash -lx
FOO
là một biến môi trường (nghĩa là .profile
chứa export FOO=something
) thì nó có sẵn cho tất cả các quy trình con, bao gồm cả foo.sh
. Nếu bạn đổi .profile
thành export FOO=something_else
thì ./foo.sh
vẫn sẽ in something
cho đến lần đăng nhập tiếp theo.
Để biết nếu bạn đang ở trong vỏ đăng nhập:
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.
Trong Bash, bạn cũng có thể sử dụng shopt login_shell
:
prompt> shopt login_shell
login_shell off
(hoặc on
trong một vỏ đăng nhập).
Thông tin có thể được tìm thấy trong man bash
(tìm kiếm Invocation). Đây là một đoạn trích:
Một vỏ đăng nhập là một vỏ có ký tự đầu tiên của đối số 0 là - hoặc bắt đầu bằng tùy chọn --login.
Bạn có thể tự kiểm tra điều này. Bất cứ khi nào bạn SSH, bạn đang sử dụng shell đăng nhập. Ví dụ:
prompt> ssh user@localhost
user@localhost's password:
prompt> echo $0
-bash
Tầm quan trọng của việc sử dụng shell đăng nhập là mọi cài đặt trong /home/user/.bash_profile
sẽ được thực thi. Dưới đây là một chút thông tin nếu bạn quan tâm (từ man bash
)
"Khi bash được gọi dưới dạng shell đăng nhập tương tác hoặc là vỏ không tương tác với tùy chọn --login, trước tiên, nó sẽ đọc và thực thi các lệnh từ tệp / etc / profile, nếu tệp đó tồn tại. Sau khi đọc tệp đó, nó sẽ tồn tại. tìm kiếm
~/.bash_profile
,~/.bash_login
và~/.profile
, theo thứ tự đó, đọc và thực thi các lệnh từ lệnh đầu tiên tồn tại và có thể đọc được. Tùy chọn --noprofile có thể được sử dụng khi trình bao bắt đầu ngăn chặn hành vi này. "
Trong một vỏ đăng nhập , argv[0][0] == '-'
. Đây là cách nó biết nó là một vỏ đăng nhập.
Và sau đó, trong một số tình huống, nó hoạt động khác nhau tùy thuộc vào trạng thái "vỏ đăng nhập" của nó. Ví dụ: shell, đó không phải là shell đăng nhập, sẽ không thực thi lệnh "logout".
man bash
, với sự nhấn mạnh được thêm vào, "Vỏ đăng nhập là một ký tự đầu tiên của đối số 0 là - hoặc bắt đầu bằng tùy chọn --login. "
Tôi sẽ giải thích câu trả lời tuyệt vời của Gilles, kết hợp với phương pháp của Timothy để kiểm tra loại vỏ đăng nhập.
Nếu bạn muốn xem mọi thứ cho chính mình, hãy thử đoạn trích và kịch bản dưới đây.
Kiểm tra xem shell có (không) tương tác không
if tty -s; then echo 'This is interactive shell.'; else echo 'This is non-interactive shell.'; fi
Kiểm tra xem shell có (không) đăng nhập không
Nếu đầu ra echo $0
bắt đầu bằng -
, vỏ đăng nhập ( echo $0
ví dụ đầu ra -bash
:). Mặt khác, nó không phải là vỏ đăng nhập ( echo $0
ví dụ đầu ra bash
:).
if echo $0 | grep -e ^\- 2>&1>/dev/null; then echo "This is login shell."; else echo "This is non-login shell."; fi;
Hãy kết hợp cả hai ở trên với nhau để có được cả hai thông tin cùng một lú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"
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
chuyển đổiBạn có thể yêu cầu rõ ràng shell tương tác khi bạn muốn chạy lệnh từ xa thông qua ssh bằng cách sử dụng -t
chuyển đổi.
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
Lưu ý: Về chủ đề tại sao chạy lệnh từ xa không login shell
có thêm thông tin ở đây .