sh файли запуску через ssh


10

У мене є кілька важливих команд, які мені потрібно виконати до запуску будь-якої оболонки sh. Це потрібно для передачі команд SSH у команді SSH ( ssh host somecommand) та інших програм, які виконують команди.

У моєму .profileце:

ihammerhands@wreckcreations:~> cat .profile
#specific environment and startup programs
export PS1="\u@wreckcreations:\w> "
export PYTHONPATH=~/python/lib/python2.4/site-packages
export PATH=$PATH:~/bin:~/python/bin

Однак це не вдається:

W:\programming\wreckcreations-site\test-hg>ssh name@host echo $PATH
Enter passphrase for key '/home/Owner/.ssh/id_rsa':
/usr/local/bin:/bin:/usr/bin

Зверніть увагу на відсутні варіанти PATH

Яке власне ім’я профілю sh? Примітка. У мене немає кореневого доступу та не хочу, щоб це застосовувалося до інших користувачів. Чи є інший спосіб зробити це?


EDIT: З'являються /bin/shпосилання на bash, що не дивно. Дивно, що мій профіль досі ігнорується. Будь-які пропозиції?


1
Мені не хочеться повторювати те, що знаходиться на сторінці man, тому просто подивіться на сторінку bash man у розділі "ІНВОКАЦІЯ". Він знаходиться вгорі і описує все, що вам потрібно знати.
camh

Ви можете спробувати використовувати ssh name@host -t echo $PATH.
Герт

Вихід @Gert такий же
TheLQ

@camh Ви думаєте, я би задав це питання, якщо я вже не перевіряв сторінки чоловіка? Я читав їх багато разів + інші дописи, але ніколи не міг знайти відповіді на це конкретне питання, оскільки я не впевнений, на якому етапі виконуються команди ssh та інші команди програми
TheLQ

1
@TheLQ: Я не знаю тебе, тому я не знаю, чи ти перевіриш сторінку чоловіка. Все, що я знав, - це відповіді саме там, тому замість того, щоб повторювати це слово за словом, я вказав вам на це. Більш конкретний вказівник - шукати неінтерактивні оболонки, оскільки це ваш сценарій ssh. Якщо щось на сторінці чоловіка не зрозуміло, можливо, ви можете задати більш конкретне запитання.
camh

Відповіді:


8

Здається, варто зазначити, що команда, яку ви згадуєте у своєму запитанні

ssh name@host echo $PATH

майже ніколи не стане в нагоді. Підстановка змінної на $ PATH виконується вашою локальною оболонкою і передається в ssh, який виконує ехо на віддаленій системі для друку вмісту змінної шляху, оскільки вона розширюється у вашій локальній системі. Ось приклад того, як я роблю щось подібне між моїм Mac та Linux машиною в моїй мережі:

LibMBP:~ will$ echo $PATH
/opt/local/bin:/opt/local/sbin:/Users/will/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/texbin:/usr/X11/bin
LibMBP:~ will$ ssh warren echo $PATH
will@warren's password: 
/opt/local/bin:/opt/local/sbin:/Users/will/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/texbin:/usr/X11/bin
LibMBP:~ will$ ssh warren 'echo $PATH'
will@warren's password: 
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
LibMBP:~ will$ 

Зверніть увагу, як мені потрібно було використовувати лапки, щоб запобігти розширенню мінливої ​​оболонки.


У землі Windows Cygwin окремі цитати нічого не роблять у вікні Cygwin або Command. Як не дивно, подвійні лапки змушують PATH повністю розширюватися до моєї локальної машини в Cygwin. Тож те, що мені давав ssh, не був моїм шляхом, це був сервер
TheLQ

@TheLQ Одиночні лапки необхідні в підказці unix (включаючи Cygwin), але вам не потрібно жодних лапок у cmd-підказці.
Жил "ТАК - перестань бути злим"

12

~/.profileвиконується лише оболонками для входу. Програма, яка викликає оболонку, вирішує, чи буде оболонка оболонкою для входу (шляхом введення в -якості першого символу нульового аргументу виклику оболонки). Зазвичай він не виконується під час входу для виконання певної команди.

Зокрема, OpenSSH викликає оболонку входу, лише якщо ви не вказали команду. Отже, якщо ви вкажете команду, ~/.profileвона не буде прочитана.

OpenSSH дозволяє встановити змінні середовища на стороні сервера. Це повинно бути включено в налаштуваннях сервера з PermitUserEnvironmentдирективою. Змінні можна встановити у файлі ~/.ssh/environment. Припустимо, що ви використовуєте аутентифікацію відкритих ключів, ви також можете встановити змінні для кожного ключа у ~/.ssh/authorized_keys: додати environment="FOO=bar"на початку відповідного рядка.

Ssh також підтримує надсилання змінних середовища. У OpenSSH використовуйте SendEnvдирективу в ~/.ssh/config. Однак певна змінна середовище повинна бути включена AcceptEnvдирективою в конфігурації сервера, тому це може не спрацювати для вас.

Одне, на мою думку, завжди працює (як не дивно), якщо ви використовуєте аутентифікацію відкритих ключів, - це (ab) використання command=опції у authorized_keysфайлі . Ключ з commandопцією хороший лише для запуску зазначеної команди; але команда у authorized_keysфайлі працює зі змінною середовища, SSH_ORIGINAL_COMMANDвстановленою командою, яку вказав користувач. Ця змінна порожня, якщо користувач не вказав команду і тому очікував інтерактивну оболонку. Таким чином, ви можете використовувати щось подібне в цьому ~/.ssh/authorized_keys(звичайно, це не застосовуватиметься, якщо ви не використовуєте цей ключ для автентифікації):

command=". ~/.profile; if [ -n \"$SSH_ORIGINAL_COMMAND\" ]; then eval \"$SSH_ORIGINAL_COMMAND\"; else exec \"$SHELL\"; fi" ssh-rsa 

Інша можливість - написати сценарій обгортки на сервер. Щось подібне в ~/bin/ssh-wrapper:

#!/bin/sh
. ~/.profile
exec "${0##*/}" "$@"

Потім зробіть символічні посилання на цей сценарій під назвою rsync, unisonі т.д. Pass --rsync-path='bin/rsync'на rsyncкомандному рядку, і так далі для інших програм. Крім того, деякі команди дозволяють вказати цілий фрагмент оболонки для запуску віддалено, що дозволяє зробити команду самостійною: наприклад, з rsync ви можете використовувати --rsync-path='. ~/.profile; rsync'.

Є ще одна алея, яка залежить від того, чи буде оболонка входу bash або zsh. Bash завжди читає, ~/.bashrcколи на нього викликається rshd або sshd, навіть якщо він не є інтерактивним (але не, якщо він називається як sh). Зш завжди читає ~/.zshenv.

## ~/.bashrc
if [[ $- != *i* ]]; then
  # Either .bashrc was sourced explicitly, or this is an rsh/ssh session.
  . ~/.profile
fi

## ~/.zshenv
if [[ $(ps -p $PPID -o comm=) = [rs]shd && $- != *l* ]]; then
  # Not a login shell, but this is an rsh/ssh session
  . ~/.profile
fi

А як щодо команд, які виконують інші команди? У цьому випадку це були беркурійські гачки. Меркуріалу потрібно стати на шляху, щоб гак навіть
міркував

Використовуйте будь-який із методів, які я вказав, щоб ваш профіль запускався в неінтерактивних командах ssh. Один з них ( command=в authorized_keys) працює прозоро. Іншим потрібна певна оболонка або параметри в конфігурації ssh-сервера. Меркурійський еквівалент --rsync-pathє --remotecmd.
Жил "ТАК - перестань бути злим"

command=
Декому

1

Зазвичай під час входу, bash читає команди з:

~ / .bash_profile
~ / .bashrc

З сторінки bash man:

~ / .bash_profile
Персональний файл ініціалізації, виконаний для оболонок входу

~ / .bashrc
Індивідуальний файл запуску за допомогою інтерактивної оболонки


0

У мене не вистачає часу, щоб перевірити це, але дивлячись на сторінки чоловіка, які я знайшов:

man bash: коли bash запускається неінтерактивно, для запуску сценарію оболонки, наприклад, він шукає змінну BASH_ENV у середовищі, розширює його значення, якщо вона з’являється там, і використовує розширене значення як ім'я файлу для читати та виконувати. Bash поводиться так, ніби виконується така команда: if [-n "$ BASH_ENV"]; тоді . "$ BASH_ENV"; fi, але значення змінної PATH не використовується для пошуку імені файлу.

man ssh: ~ / .ssh / environment Містить додаткові визначення змінних середовища; див. ЕКОЛОГІЯ вище.

Комбінація підказує, як можна змусити ssh виконати свій .profile

На жаль, мій сервер має PermitUserEnvironment за значенням за замовчуванням no, завдяки чому це не працює для мене (і, як я вже сказав, у мене більше немає часу грати з ним).


Навіть якщо я можу змусити SSH працювати, чітко зазначивши деякі змінні середовища в оточенні, це все одно не допоможе виправити виконання мого профілю, коли інші програми викликають команди
TheLQ

У вашому прикладі все, що ви робите, - це налаштування змінних середовища, що ще ви хочете зробити?
kasterma

0

(видалено ... може мати лише одне гіперпосилання як новий користувач ~)

Оновлення

Вибачте, я не бачив, що мова йде про неінтерактивний сеанс, до якого вищевказане посилання не поширюється.

Коли Bash запускається в режимі сумісності SH, він намагається максимально наблизити поведінку до запуску історичних версій sh, дотримуючись стандарт POSIX®. Прочитані файли профілю - це / etc / profile та ~ / .profile, якщо це оболонка для входу.

Якщо це не оболонка для входу, оцінюється змінна середовище ENV, і отримане ім'я файлу приймається як ім'я запускового файла.

Після зчитування файлів запуску Bash переходить у режим сумісності POSIX (r) (для запуску, а не для запуску!).

Bash запускається в режимі сумісності sh, коли:

  • ім'я базового файлу в argv [0] - sh (:!: Увага шановні користувачі Linux розумні ... / bin / sh можуть бути пов'язані з / bin / bash, але це не означає, що воно діє як / bin / bash :! :)

Отже, питання полягає в тому, чому він не виконує його, навіть якщо ваша оболонка запускається так.

Джерело


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