Как я могу передать переменную окружения через команду ssh? [Дубликат]

43

Как передать значение в команду ssh, чтобы среда, запускаемая на хост-компьютере, запускалась с определенной переменной среды, выбранной по моему выбору?

РЕДАКТИРОВАТЬ: цель состоит в том, чтобы передать текущий рабочий стол kde (из dcop kwin KWinInterface currentDesktop) в новую созданную оболочку, чтобы я мог передать nfs-местоположения моему экземпляру JEdit на исходном сервере, который уникален для каждого рабочего стола KDE. (Используя такой механизм, как emacsserver / emacsclient )

Причина, по которой несколько экземпляров ssh могут быть запущены одновременно, заключается в том, что когда я настраиваю свою среду, я открываю кучу разных экземпляров ssh для разных машин.

Росс Роджерс
источник

Ответы:

19

~/.ssh/environmentФайл может быть использован для установки переменных , которые вы хотите сделать доступными для удаленных команд. Вам придется включить PermitUserEnvironmentв конфигурации sshd.

Переменные, установленные таким образом, экспортируются в дочерние процессы, поэтому вы можете:

echo "Foo=Bar" > sshenv
echo "Joe=37" >> sshenv
scp sshenv user@server:~/.ssh/environment
ssh user@server myscript

и myscript будет знать, что Фу - это Бар, а Джо - 37.

Джон Т
источник
3
переменная должна потенциально меняться при каждом вызове ssh
Росс Роджерс
1
Может быть, лучше описать, что вы пытаетесь сделать и почему. Могут быть и другие решения. Файл среды должен генерироваться динамически при каждом вызове ssh, что не является невозможным.
EmmEff
Что изменится? Значения этих переменных или даже их имена?
ИннаМ 30.09.09
2
Этот ответ на самом деле не отвечает на вопрос.
интуитивно
1
Это сломается, если два процесса
попытаются
55

SendEnvВариант ваш парень.

~ / .ssh / config: (локально)

SendEnv MYVAR

/ etc / ssh / sshd_config: (на удаленном конце)

AcceptEnv MYVAR

Теперь, каким бы ни было $MYVARлокальное значение , оно становится доступным и в удаленном сеансе.
Если вы входите в систему несколько раз, у каждого сеанса будет своя копия $MYVAR, возможно с разными значениями.

~/.ssh/environmentпредназначен для других целей. Он действует как $ENVфайл при удаленном выполнении команд без оболочки .


источник
6
также может быть передано (более полезно) через командную строку ssh myserver -o SendEnv="MYVAR", так что вы можете сделать его динамическим в сценариях.
Майк Кэмпбелл
31

Вы можете передавать значения с помощью команды, аналогичной следующей:

ssh username@machine VAR=value cmd cmdargs

Вы можете проверить с:

ssh machine VAR=hello env

На tcsh похоже следующее работает:

ssh machine "setenv VAR <value>; printenv"
Waltor
источник
Похоже, это хорошо работает для сред Bash. Жаль, что я в корпоративной среде tcsh.
Росс Роджерс
2
Как я могу использовать сеанс в интерактивном режиме?
luckydonald
1
Обратите внимание, что первый пример работает только для первой команды, если вы объединяете команды вместе (с &&). Использование bash export VAR=value;вместо setenv в третьем виде работает для этого случая.
contrebis
2
Это то, что я в итоге сделал! Куда бы вы ни пошли, возьмите с собой свое окружение. Вы можете сделать это так: ssh user@host "$(<env_to_source.sh) command ..." . В env к источнику у меня есть export var=value ; отдельные строки (помните точку с запятой).
Томаш Гандор
@TomaszGandor: годы спустя, все еще отлично - позволяет мне даже передавать сложные вещи, такие как PROMPT_COMMAND, без необходимости беспокоиться о побеге :-) 1000 спасибо.
Красная таблетка
29

Там также ужасный, ужасный взлом.

Если ваш сценарий потребляет переменную на удаленном конце (то есть вы можете назвать ее как угодно), вы можете использовать переменные локали. Любая переменная формы LC_ * будет передана дословно, без каких-либо требований к конфигурации.

Например, у нас есть ряд бастионных серверов на одном из моих клиентов. Я ненавижу подключаться к нему, просто подключаться к другому серверу ... и другому серверу ... каждый раз. У меня есть скрипт, который ведет себя так же, как SSH, за исключением того, что он умный.

По сути, если установлен LC_BOUNCE_HOSTS, он разбивает его на пробелы и снимает первый хост. Затем он прыгает и запускает тот же сценарий. На конечном узле этот список в конечном итоге пуст, поэтому он запускает команду. У меня также есть режим отладки (который отлично подходит во время сетевых проблем), который устанавливается LC_BOUNCE_DEBUG. Поскольку ssh магически передает все это мне, мне не нужно ничего делать, кроме как распознать конец списка хостов (что я делаю с опцией -).

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

Jayson
источник
2
Почему вы используете что-то подобное вместо встроенной ProxyCommandопции OpenSSH ? Отредактируйте свой ~/.ssh/configи добавьте блок как Host *.example.com: ProxyCommand -ssh -W %h:%p bastionhostи позвольте ему туннелировать ваши соединения для вас
Кирк Штраузер
1
Для туннелей это не так уж и плохо. Для env vars есть две причины: во-первых, PermitUserEnvironment требует права администратора для настройки на сервере, чтобы передать их напрямую. Передать их через командную строку также очень сложно, чтобы правильно выбраться. Во-вторых, необходимо преодолеть несколько бастионов, делая это немного сложнее, особенно когда исходному хосту не ясно, какой путь выбрать к определенному целевому хосту. Проще сказать: «bounce-ssh bast1 bast2 nodeX - rm -rf /», чем поддерживать маршруты для постоянно растущей совокупности хостов в серии файлов ssh-config.
Джейсон
Хороший улов !! Так замечательно и немного грязно !!
zw963 14.12.16
2
Это ужасно Браво. 👏
Пи Дельпорт
1
Это ужасно здорово, спасибо! Я использовал это для еще одного ужасно хорошего взлома ! :)
поясничный
1
bla="MyEnvSelection=dcop"
ssh user@host "export $bla && ./runProg"

На Bash я проверил с:

$ echo '#!/bin/sh' > readEnv.sh
$ echo 'echo "MyEnv: "$MyEnvFromSSH' >> readEnv.sh

$ scp readEnv.sh user@host:~/
$ bla="MyEnvFromSSH=qwert"
$ ssh user@host "export $bla && ./readEnv.sh"
Zeh
источник