`ssh <host>` là shell đăng nhập, nhưng` ssh <host> <lệnh> `thì không?


12

Tôi nhận thấy rằng khi tôi chạy một lệnh trực tiếp trên máy chủ SSH bằng ssh <host> <command>cú pháp, tôi thấy đầu ra của .bashrcnhưng không phải là đầu ra của .bash_profile(hoặc .profile).

Chẳng hạn, nếu tôi đặt lệnh sau ở đầu cả hai tệp,

echo ${BASH_SOURCE[0]}

và nguồn thủ công .bash_profile(nguồn nào .bashrclần lượt), tôi sẽ thấy

$ . .bash_profile
.bash_profile
.bashrc

Đây là cùng một đầu ra tôi thấy nếu tôi đăng nhập vào máy tính này từ xa thông qua SSH, sử dụng ssh <host>hình thức của lệnh. (Và nếu tôi .bash_profiletạm thời cất giấu ở một nơi khác, cả hai dòng này sẽ không bị lặp lại.)

Tuy nhiên, nếu tôi thực thi một lệnh trực tiếp trên máy từ xa với ssh <host> <command>hình thức ssh, thì đầu ra trông như thế này:

$ ssh <host> echo foo
/home/rlue/.bashrc
foo

Sự hiểu biết của tôi là sự khác biệt giữa .bash_profile.bashrccái trước là cho shell đăng nhập trong khi cái sau là cho shell tương tác, không đăng nhập .

Tôi đã kết luận như sau:

  1. ssh <host>chỉ nguồn .bash_profile, trong khi
  2. ssh <host> <command>chỉ nguồn .bashrc, có nghĩa là
  3. cái trước là shell đăng nhập và cái sau thì không.

Những kết luận này có đúng không? Tại sao được ssh <host> <command>coi là một vỏ tương tác, không đăng nhập? Không phải SSH vẫn đăng nhập vào máy từ xa để thực thi lệnh sao?


sản lượng của .bashrc? Tập tin đó không được phép tạo ra bất kỳ đầu ra nào. Bất kỳ đầu ra từ .bashrccó thể phá vỡ tất cả các công cụ sử dụng ssh như vận chuyển của họ.
kasperd

Đủ công bằng. Trong trường hợp này, một vài dòng trong .bashrcđó đã đưa ra một lỗi, trong khi các dòng tương tự .bash_profilethì không. Tôi đã nhân cơ hội để điều tra sự khác biệt trước khi sửa các dòng vi phạm.
Ryan Lue

Câu trả lời:


12

OpenSSH (rất có thể là những gì bạn đang chạy) quyết định có tạo shell đăng nhập hay không và nó chỉ làm như vậy nếu bạn không chạy một lệnh cụ thể. Từ man ssh:

 If command is specified, it is executed on the remote host instead of a
 login shell.

Vì vậy, đó là một lựa chọn triển khai cho máy chủ ssh cho dù nó có muốn tạo shell đăng nhập hay không và nếu bạn đưa ra lệnh để chạy, thì không.

Mặc dù sshthực hiện đăng nhập, nhưng nếu bạn có nó thực thi một lệnh và thoát, thì nó thực sự giống với việc tạo một shell chỉ để chạy lệnh đó hơn là tạo môi trường đăng nhập. Dường như, cho rằng, những người viết OpenSSH đã quyết định coi nó như một loại nhiệm vụ.

Họ tạo ra một shell không tương tác, không đăng nhập để thực thi lệnh, bởi vì đó là tinh thần của việc chạy một lệnh trong ngữ cảnh / shell khác. Thông thường, mặc dù, các vỏ không tương tác sẽ không tự động tạo nguồn ~/.bashrcrõ ràng đang xảy ra ở đây. bashđang thực sự cố gắng giúp chúng tôi ra khỏi đây. Từ các tài liệu

Được gọi bởi trình nền shell từ xa

Bash cố gắng xác định khi nào nó đang được chạy với đầu vào tiêu chuẩn của nó được kết nối với kết nối mạng, như khi được thực thi bởi trình nền shell từ xa, thường là rshd hoặc sshd shell shell an toàn. Nếu Bash xác định nó đang được chạy theo kiểu này, nó sẽ đọc và thực thi các lệnh từ ~ / .bashrc, nếu tệp đó tồn tại và có thể đọc được. Nó sẽ không làm điều này nếu được gọi là sh. Tùy chọn --norc có thể được sử dụng để ngăn chặn hành vi này và tùy chọn --rcfile có thể được sử dụng để buộc một tệp khác được đọc, nhưng cả rshd và sshd thường không gọi shell với các tùy chọn đó hoặc cho phép chúng được chỉ định.


"... nó được thực thi trên máy chủ từ xa thay vì vỏ đăng nhập." Tôi không nhận được sự phân đôi này. Là lệnh được thực thi trên máy chủ từ xa thay vì trong vỏ đăng nhập , hoặc lệnh được thực thi trên máy chủ từ xa, thay vì vỏ đăng nhập được thực thi ở đó? Nếu trước đây, nó như thế nào / hoặc? (không phải bình thường cả hai sao? ) Nếu sau này, nó vẫn được thực thi trong bối cảnh của một số shell, phải không? (một tương tác, không đăng nhập?) Vì vậy, câu hỏi của tôi cũng là về ngữ nghĩa - "shell shell" nghĩa là gì, và tại sao OpenSSH sẽ được thiết kế để không tạo một cho một lệnh?
Ryan Lue

@RyanLue Các "hương vị" khác nhau của mỗi shell giúp cho một số tác vụ nhất định trở nên dễ dàng hơn / an toàn hơn / được tối ưu hóa, v.v. Trong khi thực sshhiện yêu cầu đăng nhập, người thực hiện dường như đã quyết định rằng trong một số trường hợp, ví dụ, yêu cầu nó thực thi lệnh và trả về, thực hiện không cần / hưởng lợi từ các bước bổ sung mà shell đăng nhập thực hiện và vì vậy họ bỏ qua điều đó. Vì vậy, thực sự có một shell đang chạy, tôi cho rằng chủ yếu là để thiết lập môi trường và vì shell sẽ không được cung cấp cho người dùng đã đăng nhập, nên họ coi nó như thể người dùng mới bắt đầu một shell mới để chạy nó lệnh
Eric Renouf

"Vì vậy, thực sự có một cái vỏ đang chạy, tôi cho rằng chủ yếu là để thiết lập môi trường ..." <nhưng tôi chỉ thử nghiệm cái này, và có vẻ như ssh <host> <command>nó không kế thừa môi trường của bất kỳ shell đăng nhập hiện có nào. Ví dụ, $ ssh <host> \$PATHtrả về đường dẫn như nó sẽ không có nguồn .bash_profile(hoặc .profile, như nó đã từng) ... Theo nghĩa thực tế, tại sao bạn muốn phá vỡ bước đó?
Ryan Lue

Rõ ràng ... những người triển khai đã quyết định rằng trong một số trường hợp, ví dụ, yêu cầu nó thực thi lệnh và trả lại, không cần / hưởng lợi từ các bước bổ sung mà trình đăng nhập thực hiện và vì vậy họ bỏ qua điều đó. <cũng, đặc biệt tìm kiếm làm rõ / cái nhìn sâu sắc về sự lựa chọn thiết kế này. Tôi định nghĩa của tôi PATHtrong .profile- mà không phải là chính xác là điều mà bạn muốn nạp trước khi chạy một lệnh tùy ý trên một máy chủ từ xa?
Ryan Lue

1
@RyanLue máy chủ Boks ssh phân biệt cách sử dụng ssh riêng biệt và có thể cấp quyền cho mỗi máy chủ. Đăng nhập từ xa, thực thi từ xa, sao chép từ xa, Có thể điều này giúp hiểu lý do tại sao bạn sẽ có hành vi bạn mô tả. Đăng nhập từ xa (sử dụng tương tác) có thể là quá nhiều để yêu cầu trong một môi trường bảo mật cao. Openssh có thể bị hạn chế bằng cách sử dụng rbash / rksh và 'logout' trong .bash_profile hoặc chroot.
bbaassssiiee

4

do tại sao hành vi này nằm ở mức thấp hơn so với shell: ssh host(trường hợp "shell đăng nhập") sử dụng một giả ngẫu nhiên trên máy chủ từ xa, để liên lạc giữa sshdquá trình máy chủ và shell; ssh host commandsử dụng đường ống giữa sshdcommand, thay vào đó. Pseudotermals là cần thiết để sử dụng tương tác trình thông dịch lệnh, chẳng hạn như trình bao hoặc chế độ " đọc-in-in " của ngôn ngữ kịch bản lệnh; họ thực hiện một loạt các tính năng thân thiện với con người như có thể xóa lùi các lỗi chính tả. Nhưng chúng có nhiều chi phí hơn và (tùy thuộc vào cấu hình) không cho phép dữ liệu tùy ý chuyển qua không được sửa đổi, vì vậy SSH tránh sử dụng chúng khi không có tương tác.

Đôi khi lệnh của SSH / không có lệnh heuristic bị lỗi này; nó có thể được ghi đè bằng -tvà các -Tcông tắc. Chẳng hạn, để đăng nhập vào một máy từ xa và ngay lập tức gắn lại một screenphiên bị treo , bạn cần phải làm ssh -t host screen -R; ssh host screen -Rsẽ gây ra screenkhiếu nại về việc không được kết nối với thiết bị đầu cuối. Tôi không thể nghĩ đến một tình huống khi bạn thực sự muốn sử dụng -T, nhưng nó sẽ ở đó nếu bạn từng tìm thấy một tình huống .


1

Đầu tiên bạn cần xem các loại khác nhau, bạn có thể đọc điều này:

/unix/170493/login-non-login-and-interactive-non-interactive-shells

Bây giờ nếu bạn mở bashrc của bạn, bạn sẽ thấy ở đầu này:

# If not running interactively, don't do anything
[ -z "$PS1" ] && return

Điều đó có nghĩa là tùy thuộc vào cách bạn truy cập vào hệ thống, tập tin này có tải mã bên trong hay không.


Được rồi, nhưng điều này đặt ra một câu hỏi thú vị: .bashrccó thể được viết để không có nguồn gốc nếu nó được gọi trong một bối cảnh không tương tác ( nghĩa là, nếu không có câu lệnh nhắc nhở / $PS1biến). Nhưng ssh <host> <command> được quyết định là không tương tác ; đó là, nó không đưa ra một dấu nhắc lệnh. Vậy tại sao OpenSSH sẽ được thiết kế để tạo một dấu nhắc tương tác, không đăng nhập (một trong đó cố gắng tìm nguồn .bashrc) cho trường hợp sử dụng dường như không đăng nhập, không tương tác này ??
Ryan Lue
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.