Чому Bash не в змозі знайти команду, навіть якщо $ PATH вказано правильно?


9

Я вказую шлях до моєї команди у файлі / etc / profile :

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

Моя команда розташована в:

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

Отже, коли я виконую "echo $ PATH", результат виглядає так:

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

І все в порядку, але коли я намагаюся запустити свою команду через SSH, я отримую помилку:

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

Але мій шлях все ще присутній:

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

Поясніть, будь ласка, чому Bash не в змозі знайти ydisplay під час сеансу SSH та як правильно конфігурувати SSH, щоб уникнути цієї проблеми.

Більше того, якщо я вказую $ PATH у локальному файлі .bashrc у поточного користувача, все працює правильно. Але я хочу змінити лише один файл замість того, щоб вказати багато файлів для кожного користувача. Ось чому я прошу.


1
чи просто працює ydisplay? робить ssh 127.0.0.1 /usr/app/cpn/bin/ydisplayроботу?
Bananguin

@ user1129682 Так, йісплей із повним вказаним іменем працює і просто йісплей працює
SIGSEGV

Якщо ви не ввійшли в систему (у вас немає віддаленого сеансу), а лише надсилаєте команду віддалено, у вас немає доступу до змінних оточення так само, оскільки ваші .bashrc / .profile файли не виконуються. Це є причиною, оскільки вони відповідають за встановлення змінних для поточного сеансу.
mnmnc

14
Лише бічна зауваження: ssh 127.0.0.1 echo $PATHне робить те, що ви можете подумати, що робить: оболонка розширює $ PATH до того, як ssh навіть буде виконано, так що нічого не доведе і не спростує.
Ульріх Шварц

Відповіді:


5

тл; д-р

Більше , ніж запуск ssh 127.0.0.1 ydisplayджерел . Замість цього змініть свій шлях .~/.bashrc/etc/profile~/.bashrc

деталі

Єдиний час /etc/profileчитання - це коли ваша оболонка - "оболонка для входу".

З довідкового керівництва Bash :

Коли bash викликається оболонкою для входу, ... він спочатку зчитує та виконує команди з файлу / тощо / профілю

Але при запуску ssh 127.0.0.1 ydisplay, bashне починається в якості оболонки. І все-таки він читає інший файл запуску. Посібник Баша говорить:

коли ... виконаний ... sshd. ... він читає і виконує команди з~/.bashrc

Тож слід встановити свої PATHналаштування ~/.bashrc.

У більшості систем є ~/.bash_profileджерелами ~/.bashrc, тому ви можете розміщувати свої налаштування лише в тому, ~/.bashrcа не розміщувати їх в обох файлах.

Там немає ніякого стандартного способу змінити налаштування для всіх користувачів, але більшість систем мають /etc/bashrc, /etc/bash.bashrcабо аналогічні.

Якщо цього не зробити, встановіть pam_envі введіть PATHналаштування /etc/environment.

Дивись також:


1

Історично склалося, що файли профілів ( /etc/profileі ~/.profile) викликались під час входу (на текстовій консолі, що ще?) І виконували багато цілей:

  • Встановіть змінні середовища та інші параметри (наприклад, umask) для сеансу.
  • Запускайте додаткові програми на початку сеансу (наприклад, повідомлення електронною поштою).
  • Запустіть програму для сеансу, якщо вона відрізняється від оболонки (наприклад, інша оболонка або X Window).
  • Встановіть термінальні параметри (наприклад stty).
  • Встановіть параметри оболонки (наприклад, псевдоніми).

Усі ці цілі не пізніше були визначені як окремі. Оскільки сценарії профілю можуть робити речі, які мають сенс лише в інтерактивному сеансі (взаємодія терміналів, запуск інших програм), коли було введено виклик віддаленої оболонки ( rsh ), виробники rsh вирішили не викликати віддалену оболонку як оболонку входу, щоб сценарії профілю не виконувалися. (У деяких версіях rshdє можливість запустити віддалену оболонку як оболонку для входу.) Ssh скопіював цю поведінку для того, щоб стати заміною rsh.

Якщо ви хочете, щоб ваші сценарії профілю були виконані, ви можете відкрито їх викликати.

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

Зверніть увагу на команду .для завантаження скриптів профілю всередині оболонки: це команди, які потрібно виконати всередині цієї оболонки, а не зовнішня програма.

Якщо ви хочете встановити змінну середовища глобально для всіх користувачів, у багатьох системах є інший метод: замість того, щоб визначати її /etc/profile, визначте її /etc/environment. Цей файл читається через pam_envмодуль; більшість дистрибутивів Linux створені для його читання.

Якщо оболонка для входу в систему є bash, є ще одна можливість. Зазвичай не слід встановлювати змінні середовища в.bashrc (тому що вони не будуть встановлені в X сесіях, за винятком випадків, коли ви проходите через термінал з інтерактивною оболонкою, оскільки вони не будуть встановлені, якщо ви будете інтерактивно входити на текстову консоль або більше ssh, оскільки вони замінять власні налаштування, якщо ви викликаєте оболонку в іншій програмі). Однак у bash є дивна риса, яку я ніколи не розумів: вона читається ~/.bashrcза двох непов'язаних обставин:

  • в інтерактивних оболонках, які не є оболонками для входу;
  • в неінтерактивних оболонках, які не є оболонками для входу, якщо Баш вважає, що на нього було викликано rshdабо sshd.

Коли ви запускаєте команду над ssh, ви знаходитесь у другому випадку. Ви можете організувати , щоб ваш профіль читати читання /etc/profileі .profileз .bashrc. Включіть у свій код наступний код ~/.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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.