sshコマンドで環境変数を渡すにはどうすればよいですか?[複製]


43

ホストマシンで起動される環境が、選択した特定の環境変数で起動するように、sshコマンドに値を渡すにはどうすればよいですか?

編集:目標は、現在のkdeデスクトップを(dcop kwin KWinInterface currentDesktopから)作成された新しいシェルに渡して、各KDEデスクトップに固有の元のサーバーのJEdi​​tインスタンスにnfsの場所を戻すことができるようにすることです。(emacsserver / emacsclientなどのメカニズムを使用)

複数のsshインスタンスが一度に飛行できる理由は、環境をセットアップするときに、さまざまなマシンにさまざまなsshインスタンスを開いているためです。

回答:


18

この~/.ssh/environmentファイルを使用して、リモートコマンドで使用できる変数を設定できます。PermitUserEnvironmentsshd構成で有効にする必要があります。

このように設定された変数は子プロセスにエクスポートされるため、次のことができます。

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

myscriptはFooがBarで、Joeが37であることを知っています。


3
変数はすべてのssh呼び出しを潜在的に変更する必要があります
ロスロジャース

1
あなたがやろうとしていることとその理由を説明する方が良いかもしれません。他の解決策があるかもしれません。環境ファイルは各ssh呼び出しで動的に生成される必要がありますが、これは不可能ではありません。
EmmEff

何が変わるのでしょうか?それらの変数の値、あるいはその名前さえも?
innaM

2
この答えは本当に質問に答えていないようです。
直観

1
2つのプロセスが同時に値の異なるセットでこれをやろうとしている場合、これは壊れます
nafg

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"

それはbash環境でうまく機能するように見えます。残念なことに、私は企業のtcsh環境にいます。
ロスロジャーズ

2
セッションをインタラクティブに使用するにはどうすればよいですか?
ラッキードナルド

1
最初の例は、コマンドを(で&&)連結している場合にのみ、最初のコマンドで機能することに注意してください。export VAR=value;この場合、3番目の形式のsetenvの代わりにbashを使用すると機能します。
contrebis

2
これは私がやったことです!どこへ行っても、環境を持ち歩きましょう。次のようにできますssh user@host "$(<env_to_source.sh) command ..." 。env to sourceにはexport var=value ; 、別々の行があります(セミコロンを思い出してください)。
トマスガンドール

@TomaszGandor:数年後、まだ完璧-エスケープについて心配する必要なしにPROMPT_COMMANDのような複雑なものを渡すことさえできます:-) 1000ありがとう。
レッドピル

29

恐ろしい、恐ろしいハックもあります。

スクリプトがリモートエンドで変数を使用している場合(つまり、任意の名前を付けることができます)、ロケール変数を悪用できます。LC_ *の形式の変数はすべて、設定の必要なしに逐語的に渡されます。

たとえば、クライアントの1つに一連の要塞サーバーがあります。別のサーバーに接続するためだけに接続する必要はありません...そして別のサーバーに...毎回。私は、SSHと同じように動作するスクリプトを持っていますが、それは巧妙なものです。

基本的に、LC_BOUNCE_HOSTSが設定されている場合、スペースで分割し、最初のホストを剥離します。その後、バウンスして同じスクリプトを実行します。宛先ノードでは、このリストは最終的に空になるため、コマンドを実行します。また、LC_BOUNCE_DEBUGによって設定されるデバッグモード(ネットワークのトラブル時に最適)もあります。sshはこれらすべてを魔法のように私に渡すので、ホストリストの最後を認識する以外に何もする必要はありません(これは-オプションで行います)。

これを使うたびに汚い気分になりますが、試したところどこでも動作します。


2
OpenSSHの組み込みProxyCommandオプションの代わりに、なぜそのようなものを使用するのですか?を編集して~/.ssh/configブロックを追加し、Host *.example.com: ProxyCommand -ssh -W %h:%p bastionhost接続をトンネルさせます。
カークストレイザー

1
トンネルの場合、それほど悪くはありません。env変数の場合、2つの理由があります。1つは、PermitUserEnvironmentが管理者アクセスを必要とし、サーバー上で直接アクセスするように構成することです。コマンドラインを介してそれらを渡すことは、エスケープを正しくすることも非常に困難です。特に、特定の宛先ホストへのパスがソースホストから不明な場合は、2つの複数の要塞をバウンスする必要があり、これはもう少し複雑になります。「bounce-ssh bast1 bast2 nodeX-rm -rf /」と言う方が簡単です。一連のssh-configファイルでホストの進化する集団のルートを維持するよりも。
ジェイソン

良いキャッチ!! とても素敵で少し汚い!!
zw963 16

2
これは恐ろしいことです。ブラボー。👏–
パイ

1
これは恐ろしく素晴らしい、ありがとう!私はもう一つの非常に素晴らしいハックのためにそれを使用しました!:)
lumbric

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"
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.