Tại sao Bash không thể tìm thấy lệnh ngay cả khi $ PATH được chỉ định đúng?


9

Tôi đang chỉ định đường dẫn đến lệnh của tôi trong tệp / etc / profile :

export PATH=$PATH:/usr/app/cpn/bin

Lệnh của tôi nằm ở:

$ which ydisplay 
/usr/app/cpn/bin/ydisplay

Vì vậy, khi tôi thực hiện đầu ra "echo $ PATH" trông giống như:

$ echo $PATH
...:/usr/app/cpn/bin

Và mọi thứ đều ổn, nhưng khi tôi đang cố gắng khởi chạy lệnh của mình thông qua SSH thì tôi gặp lỗi:

$ ssh 127.0.0.1 ydisplay
$ bash: ydisplay: command not found

Nhưng con đường của tôi vẫn còn hiện tại:

$ ssh 127.0.0.1 echo $PATH
...:/usr/app/cpn/bin

Vui lòng giải thích cho tôi tại sao Bash không thể tìm thấy ydisplay trong phiên SSH và cách định cấu hình SSH đúng cách để tránh sự cố này.

Hơn nữa, nếu tôi chỉ định $ PATH trong tệp cục bộ .bashrc trong người dùng hiện tại thì tất cả đều hoạt động chính xác. Nhưng tôi muốn sửa đổi chỉ một tệp thay vì chỉ định nhiều tệp cho mỗi người dùng. Đây là lý do tại sao tôi hỏi.


1
không chỉ chạy ydisplaycông việc? không ssh 127.0.0.1 /usr/app/cpn/bin/ydisplaylàm việc
Bananguin

@ user1129682 Có, ydisplay với tên được chỉ định đầy đủ hoạt động và chỉ ydisplay hoạt động
SIGSEGV

Khi bạn chưa đăng nhập (bạn không có phiên từ xa) mà chỉ gửi lệnh từ xa, bạn không có quyền truy cập vào các biến môi trường theo cách tương tự vì các tệp .bashrc / .profile của bạn không được thực thi. Đây là lý do vì họ chịu trách nhiệm thiết lập các biến cho phiên hiện tại.
mnmnc

14
Chỉ cần một lưu ý phụ: ssh 127.0.0.1 echo $PATHkhông làm những gì bạn có thể nghĩ: vỏ mở rộng $ PATH trước khi ssh thậm chí được thực thi, do đó không chứng minh hoặc từ chối bất cứ điều gì.
Ulrich Schwarz

2
câu hỏi stackoverflow này có thể là một số trợ giúp
bsd

Câu trả lời:


5

tl; dr

Chạy ssh 127.0.0.1 ydisplaynguồn ~/.bashrchơn là /etc/profile. Thay đổi đường dẫn của bạn ~/.bashrcthay vào đó.

chi tiết

Thời gian duy nhất /etc/profileđược đọc là khi shell của bạn là "shell đăng nhập".

Từ tài liệu tham khảo Bash :

Khi bash được gọi như một vỏ đăng nhập, ... đầu tiên nó sẽ đọc và thực thi các lệnh từ tệp / etc / profile

Nhưng khi bạn chạy ssh 127.0.0.1 ydisplay, bashkhông được bắt đầu như một vỏ đăng nhập. Tuy nhiên, nó đọc một tập tin khởi động khác nhau. Các tay Bash Reference nói:

khi ... thực hiện bởi ... sshd. ... nó đọc và thực thi các lệnh từ~/.bashrc

Vì vậy, bạn nên đặt các PATHthiết lập của bạn trong ~/.bashrc.

Trên hầu hết các hệ thống, ~/.bash_profilenguồn ~/.bashrc, vì vậy bạn chỉ có thể đặt cài đặt của mình ~/.bashrcthay vì đặt chúng vào cả hai tệp.

Không có cách nào tiêu chuẩn để thay đổi các thiết lập cho tất cả người sử dụng, nhưng hầu hết các hệ thống có một /etc/bashrc, /etc/bash.bashrchoặc tương tự.

Không, hãy thiết lập pam_envvà đặt PATHcài đặt vào /etc/environment.

Xem thêm:


1

Trong lịch sử, các tệp hồ sơ ( /etc/profile~/.profile) được gọi khi bạn đăng nhập (trên bảng điều khiển văn bản, còn gì nữa không?) Và phục vụ nhiều mục đích:

  • Đặt các biến môi trường và các tham số khác (ví dụ: umask) cho phiên.
  • Chạy các chương trình bổ sung khi bắt đầu phiên (ví dụ: thông báo qua email).
  • Chạy chương trình cho phiên, nếu khác với shell (ví dụ: shell khác hoặc X Window).
  • Đặt tham số đầu cuối (ví dụ stty).
  • Đặt tham số shell (ví dụ: bí danh).

Tất cả những mục đích này không được xác định là riêng biệt cho đến sau này. Bởi vì các tập lệnh hồ sơ có thể thực hiện những điều chỉ có ý nghĩa trong một phiên tương tác (tương tác đầu cuối, bắt đầu các chương trình khác), khi lời gọi shell từ xa ( rsh ) được đưa ra, nên rsh đã quyết định không gọi shell từ xa làm vỏ đăng nhập, để các kịch bản hồ sơ không được thực thi. (Một số phiên bản rshdcó tùy chọn chạy shell từ xa làm vỏ đăng nhập.) Ssh đã sao chép hành vi này để thay thế cho rsh.

Nếu bạn muốn tập lệnh hồ sơ của bạn được thực thi, bạn có thể gọi chúng một cách rõ ràng.

ssh 127.0.0.1 '. /etc/profile; . ~/.profile; ydisplay'

Lưu ý lệnh .để tải các tập lệnh hồ sơ bên trong shell: chúng là các lệnh được thực thi bên trong shell đó, không phải là một chương trình bên ngoài.

Nếu bạn muốn đặt biến môi trường trên toàn cầu cho tất cả người dùng, có một phương pháp khác trên nhiều hệ thống: thay vì xác định nó trong /etc/profile, hãy xác định nó trong /etc/environment. Tập tin này được đọc thông qua các pam_envmô-đun; hầu hết các bản phân phối Linux được thiết lập để đọc nó.

Nếu vỏ đăng nhập của bạn là bash, có khả năng hơn nữa. Thông thường, bạn không nên đặt biến môi trường.bashrc (vì chúng sẽ không được đặt trong phiên X trừ khi bạn đi qua thiết bị đầu cuối có vỏ tương tác, vì chúng sẽ không được đặt nếu bạn đăng nhập tương tác trên bảng điều khiển văn bản hoặc hơn ssh, vì họ sẽ ghi đè cài đặt tùy chỉnh nếu bạn gọi shell trong chương trình khác). Tuy nhiên, bash có một tính năng lạ mà tôi chưa bao giờ hiểu: nó đọc ~/.bashrctrong hai trường hợp không liên quan:

  • trong shell tương tác không phải là shell đăng nhập;
  • trong các shell không tương tác không phải là shell đăng nhập, nếu bash nghĩ rằng nó đã được gọi bởi rshdhoặc sshd.

Khi bạn chạy một lệnh trên ssh, bạn đang ở trong trường hợp thứ hai. Bạn có thể sắp xếp để có hồ sơ của bạn đọc bằng cách đọc /etc/profile.profiletừ .bashrc. Bao gồm các mã sau đây trong ~/.bashrc:

case $- in
  *i*) :;; # this is an interactive shell, fine
  *) # This is not an interactive shell! This must be a non-interactive remote shell session.
    . /etc/profile; . ~/.profile
    return;;
esac
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.