Чому $ PATH віддаленої команди ssh відрізняється від інтерактивної оболонки?


20

У мене є користувач, який не вносив жодних змін до $ PATH в жодних точкових файлах: це саме системне налаштування за замовчуванням. З оболонки для входу:

$ ssh example.com
user@example.com:~$ cat /tmp/hello.hs
#!/bin/bash

echo "$SHELL"
echo "$PATH"

user@example.com:~$ /tmp/hello.hs
/bin/bash
/usr/local/bin:/usr/bin:/bin

Саме так, як зазначено в /etc/profile. Це я вважаю досить несподіваним:

$ ssh example.com '/tmp/hello.sh'
/bin/bash       
/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games

Як я вже говорив, немає жодної модифікації $ PATH в ~/.bashrc, ні в /etc/bash.bashrc. Ні ~/.ssh/environmentодного. ssh(1)Заявляє , що змінна середовища PATHє

Встановіть PATH за замовчуванням, як зазначено під час компіляції ssh.

але цей потік із StackOverflow та ця стаття списку розсилки припускають, що я повинен мати можливість впливати на $ PATH для даної команди, просто змінивши / etc / profile, один із файлів запуску оболонки тощо.

Що тут відбувається?

Відповіді:


16

На ssh(1)сторінці вручну: "Якщо вказана команда, вона виконується на віддаленому хості замість оболонки входу."

Отже, коротше, коли ви фактично входите в машину, bash запускається як оболонка входу і завантажує відповідні файли, коли ви віддалено підключаєтесь і видаєте команду, вона запускається замість bash, а це означає, що ці файли НЕ завантажуються. Ви можете обійти його за допомогою su -l -cабо подібного в командній частині ssh.

У деяких випадках я бачив -tаргумент і для ssh роботи (виділити tty).

Редагувати 1 :
Я думаю, що ви знайшли інформацію PATH про те, що шлях за замовчуванням (якщо ми його не перекриємо) - це той, який компілюється в sshd. Я переконався, що мій / etc / profile, / etc / bash *, локальні dotfiles тощо не містив у ньому жодної інформації PATH, тоді я ввійшов у систему і все ще мав PATH. Я шукав цього в sshd і знайшов його там. Отже, як написано на сторінці:

ahnberg@remote$ strings /usr/sbin/sshd | grep -i x11 | grep bin
/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games

Потім я додаю PATH=$PATH:/my/testв самий верхній частині мого .bashrcфайлу на віддаленому і знову перевіряю його:

ahnberg@local$ ssh ahnberg@remote "env | grep PATH"
PATH=/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games:/my/test

Тож я можу абсолютно впливати на це, і PATH за замовчуванням - це компільований у sshd. :)


Гм, ця фраза "виконана на віддаленому хості", я думаю, що це набагато більше, ніж сказано. Більш цікавий біт, який я пропустив раніше, міститься в розділі "ЕКОЛОГІЯ" тієї самої сторінки: "PATH Встановити стандартну PATH, як зазначено під час компіляції ssh." За винятком цього говорить про те, що я повинен мати можливість впливати на PATH команди.
troutwine

Ну, справа в тому, що це не оболонка для входу, тому вона не запускає / джерело / не включає файли запуску так само, як для оболонки для входу, отже, мої пропозиції спробувати. Введення речі .bashrcможе також працювати, але в цілому я б обійшов це, якщо важливо PATH. Або чому просто не вказати повні назви шляхів, якщо у вас є необхідність у командному способі запуску ssh? :)
Маттіас Анберг

Я трохи відредагував свою публікацію. Тепер є оболонка для входу, оболонка без входу та її інтерактивні / неінтерактивні варіанти. Команди SSH викликаються в оболонці користувача у неінтерактивній формі без входу. bash(1)ВИКЛИК передбачає , що ніякі завантажувальні файли не читаються таким чином, але я не можу знайти документацію по яким SSH є викликом оболонки. Це здається протилежним пов'язаним вище джерелам, якщо інші не мають / etc / ssh / sshrc файлу запуску, який у мене немає. (Звичайно, є обхідні шляхи, але справа в тому, щоб зрозуміти, як Debian SSHD обробляє контури за замовчуванням.)
troutwine

Якщо я змінюю PATH у /etc/profileоновленнях для мого віддаленого вікна, я ssh user@remotebox 'env'показує мені оновлений PATH. Те саме відбувається, якщо я додаю export PATH=$PATH:/my/testpathдо .bashrc (але в моєму випадку вгорі до файлу перед перевірками на інтерактивні оболонки ( -z "$PS1").
Mattias Ahnberg,

Оновлено моїми тестами / висновками.
Маттіас Анберг

3

Мені вдалося отримати ssh для запуску команд за допомогою віддаленого шляху шляхом запуску:

ssh dist@d6 "bash --login -c 'env'"

Тут env можна замінити будь-якою командою, яку б ви хотіли.

У мене є авторизовані ключі, тому мені не потрібен пароль для запуску команди або ssh.


3

Я придумав інше рішення, щоб виправити проблему. Моя особиста перевага - створити нові файли конфігурації замість зміни існуючих. Таким чином я можу легше визначити зміни від конфігурації за замовчуванням.

Ось зміст /etc/profile.d/ssh_login.sh:

#!/bin/sh
if [ "$SSH_CONNECTION" ]; then
    echo "User '$USER' logged in from '${SSH_CONNECTION%% *}'"
    . /etc/environment
fi

Використовуючи dropbearзамість openssh-server(це також має працювати з openssh), змінна SSH_CONNECTION встановлюється автоматично, коли я віддалено входжу в систему. Я створив нову конфігурацію профілю оболонки, щоб виявити входи SSH, відобразити деяку інформацію на екрані та, що найголовніше, завантажити глобальні налаштування середовища, /etc/environmentщоб замінити складені значення. Зверніть увагу, що це впливає лише на інтерактивні оболонки SSH, а не на віддалене виконання команд.

Крім того , якщо ви використовуєте openssh і завжди хочете завантажити глобальне середовище, незалежно від того, чи це інтерактивна оболонка, ви можете розмістити ~/.ssh/подібне посилання таким чином:

ln -s /etc/environment ~/.ssh/environment

Потім потрібно включити PermitUserEnvironmentопцію в /etc/sshd/sshd_config. Робіть це лише для довірених користувачів, оскільки це може дозволити їм обійти обмеження доступу в деяких конфігураціях за допомогою механізмів, таких як LD_PRELOAD. Будь ласка, ознайомтеся man sshd_configз додатковою інформацією, зокрема, як використовувати Matchблоки для обмеження параметрів для певних користувачів / груп.


0

Якщо ви хочете завантажувати шлях профілю, спробуйте:

#!/bin/bash -i

вгорі сценарію. Таким чином оболонка знаходиться в інтерактивному режимі під час запуску сценарію.

Коли bash викликається як інтерактивна оболонка входу, або як неінтерактивна оболонка з опцією --login, вона спочатку зчитує та виконує команди з файлу / etc / profile, якщо такий файл існує. Прочитавши цей файл, він шукає у такому порядку ~ / .bash_profile, ~ / .bash_login та ~ / .profile та зчитує та виконує команди з першого, який існує та читається. Параметр --noprofile може використовуватися, коли оболонка запускається для пригнічення такої поведінки.

http://linux.die.net/man/1/bash

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.