web-dev-qa-db-ja.com

SSHリモートコマンドは、手動で実行した場合よりも少ない環境変数を取得するのはなぜですか?

マシンにsshして実行すると正常に実行されるコマンドがありますが、次のようなリモートsshコマンドを使用して実行しようとすると失敗します。

ssh user@IP <command>

異なる環境で両方のメソッドを使用して「env」の出力を比較します。手動でマシンにログインしてenvを実行すると、実行時よりも多くの環境変数が取得されます。

ssh user@IP "env"

どうして?

214
Tom Feiner

さまざまな種類のシェルがあります。 SSHコマンド実行シェルは非対話型シェルですが、通常のシェルはログインシェルまたは対話型シェルです。以下に、man bashからの説明を示します。

ログインシェルは、引数の最初の文字が
ゼロであるもの、または--loginオプションで開始されるものです。
 
対話型シェルは1非オプション
引数なしで開始され、標準入力
とエラーの両方が端末に接続されている(isatty(3)によって決定された
として)または-cオプションなしで開始された-iオプションを使用します。 PS1は
に設定され、bashがインタラクティブな場合は$-にiが含まれ、
シェルスクリプトまたはスタートアップファイルでこの状態をテストできます。
 
以下の段落で説明しますbashがその
スタートアップファイルを実行する方法。いずれかのファイルが存在するが
を読み取れない場合、bashはエラーを報告します。ティルドは、
 EXPANSIONセクションのティルド展開で以下に説明するように、ファイル名
で展開されます。
 
 bashが対話型ログインシェルとして起動される場合、またはas 
 --loginオプションを指定した非対話型シェル。最初に
ファイルが存在する場合、ファイル/ etc/profileからコマンドを読み取り、実行します
。そのファイルを読み取った後、
〜/ .bash_profile、〜/ .bash_login、および〜/ .profileをその
の順序で探し、最初のコマンド[.____からコマンドを読み取って実行します。]存在し、読み取り可能です。 --noprofileオプションは、シェルの起動時に
を使用して、この動作を禁止できます
 ior。
 
ログインシェルが終了すると、bashはコマンドを読み取り、実行します
ファイル〜/ .bash_logoutが存在する場合。
 
ログインシェルではない対話型シェルが開始されると
、bashはコマンドを読み取り、実行します〜/ .bashrc、
からそのファイルが存在する場合。 
 --norcオプションを使用すると、これを禁止できます。 --rcfile fileオプションは、bash 
の代わりに
〜/ .bashrc。
 
の代わりにファイルからコマンドを強制的に読み取り、実行します、Shell 
スクリプトを実行するには、たとえば、
環境で変数BASH_ENVを探し、そこに値があれば展開します。
は展開された値を読み取り
して実行するファイルの名前。 bashは、次のコマンド
が実行されたかのように動作します。
 if [-n "$ BASH_ENV"];その後。 「$ BASH_ENV」; fi 
が、PATH変数の値はファイル名の検索
に使用されません。
 
159
Vinko Vrsalovic

コマンドを実行する前にプロファイルを入手するのはどうですか?

ssh user@Host "source /etc/profile; /path/script.sh"

これを~/.bash_profile~/.bashrcなどに変更するのが最善の方法です。

(As ここ(linuxquestions.org)

109
Ian Vaughan

リモートsshコマンドの実行時にシェル環境がロードされません。 ssh環境ファイルを編集できます。

vi ~/.ssh/environment

その形式は次のとおりです。

VAR1=VALUE1
VAR2=VALUE2

また、PermitUserEnvironment = yesオプションのsshd構成を確認してください。

81
dpedro

私は同様の問題を抱えていましたが、最終的には〜/ .bashrcだけで十分であることがわかりました。

ただし、Ubuntuでは、〜/ .bashrcの処理を停止する行をコメントする必要がありました。

#If not running interactively, don't do anything
[ -z "$PS1" ] && return
60
tomaszbak

この問題の簡単な解決策は、ターゲットシステムで実行しようとしたscript.shファイルの先頭にソース/ etc/profileを追加することでした。ここのシステムでは、これにより、script.shに必要な環境変数がログインシェルから実行されているかのように構成されました。

以前の応答の1つでは、〜/ .bashr_profileなどを使用することが提案されました。私はこれに多くの時間を費やしませんでしたが、これに関する問題は、あなたがログインしたソースシステムのシェルとは異なるターゲットシステムのユーザーにsshする場合、これがソースシステムユーザーを引き起こすように見えました〜に使用される名前。

4
Chuck

〜/ .bashrcの非対話型シェルのチェックの上に、必要な環境変数をエクスポートするだけです。

3