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? Примечание. У меня нет root-доступа, и я не хочу, чтобы это применялось к другим пользователям. Есть ли другой способ сделать это?


РЕДАКТИРОВАТЬ: появляется /bin/shссылки на bash, что не удивительно. Что удивительно, так это то, что мой профиль все еще игнорируется. Какие-либо предложения?


1
Мне не хочется повторять то, что находится на странице руководства, поэтому просто загляните на страницу руководства bash в разделе «ПРИЗНАНИЕ». Это около вершины и описывает все, что вам нужно знать.
Camh

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

Выход @Gert такой же
TheLQ

@camh Как ты думаешь, я бы задал этот вопрос, если бы я не проверил страницы руководства? Я читал их много раз + другие посты, но никогда не мог найти ответ на этот конкретный вопрос, так как я не уверен, на каком этапе выполняются команды ssh и команды других программ
TheLQ

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

Ответы:


8

Кажется, стоит отметить, что команда, которую вы упоминаете в своем вопросе

ssh name@host echo $PATH

почти никогда не будет полезным. Подстановка переменной для $ PATH выполняется вашей локальной оболочкой и передается в ssh, который выполняет echo на удаленной системе, чтобы распечатать содержимое переменной пути, поскольку она развернута в вашей локальной системе. Вот пример того, как я делаю нечто подобное между моим 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 или командной строке. Как ни странно, двойные кавычки заставляют 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директиву in ~/.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

Как насчет команд, которые выполняют другие команды? В этом случае это будут Mercurial Hooks. Mercurial должен быть на пути, чтобы ловушка даже думала о работе
TheLQ

Используйте любой из методов, которые я указал, чтобы ваш профиль запускался неинтерактивными командами ssh. Один из них ( command=в authorized_keys) работает прозрачно. Другие требуют определенной оболочки или параметров в конфигурации сервера ssh. Ртутный эквивалент --rsync-pathесть --remotecmd.
Жиль "ТАК - перестань быть злым"

Для некоторых было бы полезно включить ту же command=команду, что и в вашем посте superuser.com/a/207262/137762
mforbes,

1

Обычно при входе в систему bash читает команды из:

~ / .bash_profile
~ / .bashrc

Со страницы руководства bash:

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

~ / .bashrc
Отдельный файл запуска для каждой интерактивной оболочки


0

У меня заканчивается время, чтобы проверить это, но я смотрю справочные страницы, которые нашел:

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

man ssh: ~ / .ssh / environment Содержит дополнительные определения переменных среды; см. ОКРУЖАЮЩАЯ СРЕДА, выше.

Комбинация подсказывает, как вы можете заставить ssh выполнить ваш .profile

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


Даже если бы я мог заставить работать SSH, явно указав некоторые переменные среды в среде, это все равно не поможет исправить выполнение моего профиля, когда другие программы вызывают команды
TheLQ

В вашем примере все, что вы делаете, это устанавливаете переменные окружения, что еще вы хотите сделать?
Кастерма

0

(удалено ... может иметь только одну гиперссылку в качестве нового пользователя ~)

Обновить

Извините, я не видел, чтобы речь шла о неинтерактивном сеансе, к которому вышеуказанная ссылка не относится.

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

Если это не оболочка входа в систему, оценивается переменная среды ENV, и полученное имя файла принимается за имя файла запуска.

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

Bash запускается в режиме совместимости sh, когда:

  • Базовое имя файла в argv [0] - это sh (:!: Внимание, дорогие умные пользователи Linux ... / bin / sh может быть связан с / bin / bash, но это не значит, что он действует как / bin / bash : :)

Итак, вопрос в том, почему он не запускается, даже если ваша оболочка запускается так.

Источник


Я посмотрел, но, как я сказал camh, я не знаю, на каком этапе выполняются ssh-команды и другие программные команды. Я уже много раз читал страницы руководства и другие руководства
TheLQ
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.