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


239

マシンにsshして実行しても問題なく動作するコマンドがありますが、次のようなリモートsshコマンドを使用して実行しようとすると失敗します。

ssh user@IP <command>

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

ssh user@IP "env"

なぜか?


30
なぜこの質問はトピック外として閉じられているのですか?
jottr 2014年

13
おそらくそれはプログラミング関連ではないからです。閉じられるのではなく、スーパーユーザーに移動されているはずです。
ダニエルH

8
bashスクリプト言語ではないですか?
Dan Nissenbaum

Debian 8では、何らかの理由で/ etc / passwdでシェルをbashに変更する必要がありました。/ bin / shがbashをポイントするようにダッシュを再構成しても、役に立ちませんでした。
user1050755

回答:


173

シェルにはさまざまなタイプがあります。SSHコマンド実行シェルは非対話型シェルですが、通常のシェルはログインシェルまたは対話型シェルです。man bashからの説明は次のとおりです。

       ログインシェルは、引数の最初の文字
       ゼロは-または--loginオプションで開始された-です。

       対話型シェルは、オプションなしで起動されたシェルです
       引数と-cオプションなしの標準入力
       とエラーは両方とも端子に接続されています
       isatty(3))、または-iオプションで開始されたもの。PS1は
       setおよび$-bashが対話型の場合はiを含め、
       この状態をテストするためのシェルスクリプトまたはスタートアップファイル。

       次の段落では、bashがどのように実行するかについて説明します
       スタートアップファイル。いずれかのファイルは存在するが存在できない場合
       読み取り、bashはエラーを報告します。チルダはファイルで展開されています
       以下の「チルダ拡張」で説明する名前
       拡張セクション。

       bashが対話型ログインシェルとして呼び出されたとき、または
       --loginオプション付きの非対話型シェル、最初に
       / etc / profileファイルからコマンドを読み取り、実行します。
       そのファイルは存在します。そのファイルを読んだ後、それは探します
       〜/ .bash_profile、〜/ .bash_login、〜/ .profile、
       順序付け、最初のコマンドからのコマンドの読み取りと実行
       それは存在し、読み取り可能です。--noprofileオプションは
       シェルが起動したときに使用して、この動作を抑制します
       ior。

       ログインシェルが終了すると、bashはコマンドを読み取って実行します
       ファイル〜/ .bash_logoutが存在する場合。

       ログインシェルではないインタラクティブシェルが
       起動すると、bashは〜/ .bashrcからコマンドを読み取って実行します。
       そのファイルが存在する場合。これは、
       --norcオプション。--rcfile fileオプションはbashを強制します
       代わりにファイルからコマンドを読み取って実行する
       〜/ .bashrc。

       bashが非対話的に開始されたときに、シェルを実行する
       たとえば、スクリプトは変数BASH_ENVを探します
       環境、そこに表示されている場合はその値を拡張し、
       展開された値を読み取るファイルの名前として使用します
       そして実行します。bashは次のコマンドのように動作します
       実行されました:
              if [-n "$ BASH_ENV"]; その後。"$ BASH_ENV"; fi
       しかし、PATH変数の値は検索に使用されません
       ファイル名。


7
正解です。これはまさに問題でした。必要な環境変数は/ etc / bashrcにあり、非インタラクティブモードではソースされません。それらを/ etc / profileに移動することで問題は解決しました。どうもありがとうございました!
Tom Feiner、

1
この答えは部分的な解決策にすぎません。次に、いくつかの詳細情報を示します。別の環境変数を追加します(たとえば、SOURCED_SYSTEM_ETC_BASHRCをエクスポートします)。ソースになるさまざまなファイルに追加します。次に、Jenkinsの出力でその一意の変数を探します。私の場合、/ etc / bashrcを更新して 'export SOURCED_SYSTEM_ETC_BASHRC = yes'を含めると、その変数がノードのJenkinsログに表示されました。したがって、私の場合、jenkinsスレーブの環境変数を設定するには、/ etc / bashrcに移動する必要があります。Jenkins sshログインは、 / etc / bashrcからのみ提供されます。
Coder Roadie、2016年

訂正:/ etc / bashrcではなく、/ etc / bash.bashrcを意味しました。
Coder Roadie

37
これはかなりのテキストの壁ssh user@host "bash --login -c 'command arg1 ...'"です。リモートシェルがログイン環境をセットアップするように強調表示する価値があると思います。あなたが引用したセクションは言及して--loginいますが、これを見逃しやすいでしょう。
codebeard 2016年

この投稿をありがとうございます。以前ssh <ssh options> <IP> bash --login my_script.shはリモートマシンでスクリプトを実行し、JAVA_HOME
ごちそうを作って、次の

117

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

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

あなたはそれを変更するには、それとの最良を見つけるかもしれない~/.bash_profile~/.bashrcまたは何でも。

ここ(linuxquestions.org)のように


1
この問題があった場合、このソリューションはうまく機能しました。
Sam152

10
環境を調達するためだけに常に追加のコードを入力する必要があるのはばかげています!
Michael

4
このようなことを繰り返し入力することはめったになく、通常はスクリプト内にあります。そのため、機能する限り、「余分なコード」がいくつあっても問題ありません:tm:
Ian Vaughan

1
/ etc / profileと〜/ .bash_profile(パスへのユーザーの追加を取得するため)の両方をソースにした場合は機能しますが、醜いです。コマンド(私の場合はxterm)に「対話型」ログインを使用してリモートマシンの完全なユーザー固有のパスを取得するように指示する簡単な方法が必要ですか?
ジェス

ssh $ 1 "source〜/ .bashrc;〜/ temp_unix.sh"ここでtemp_unix.shはエクスポートMANI_HOME = "mani deepak"を持っていますが、機能していません。
mani deepak 14年

90

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

vi ~/.ssh/environment

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

VAR1=VALUE1
VAR2=VALUE2

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


1
完璧!+100できれば:)
デクスター

VisualGDBは「bash:gcc:コマンドが見つかりません」というエラーで失敗しましたが、このソリューションではそれを修正しました。
KalenGi 2013

素晴らしい。私がこの数年前に知っていたらよかったのに。
重力

これは完璧な答えです!
ジラポン2015

1
@ pg2455常にサーバーでsshdを構成できるわけではない(またはすべてに対してsshdを有効にしたくない)場合でも、ユーザー環境を編集できます
dpedro

63

私にも同様の問題がありましたが、最終的に〜/ .bashrcが必要なすべてであることがわかりました。

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

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

8
または、すべての「非インタラクティブ」コードをその行の上に置くこともできます。
machineghost

美しく、たくさんの時間を節約してくれました:)ありがとう
ランスポラール

ありがとう。returnステートメントを含むファイルがにあることを追加するだけ/etc/bash.bashrcです。
adarshr 2014

それを変更せずにサーバーでこのコードをバイパスする方法はありますか?
Yoni

スクリプトが機能しない理由を理解するために、多くの時間を費やしました。これらの行を.bashrcに入れるのは良い考えだと誰が思いましたか???
Sharcoux

4

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

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


パーフェクト!問題に対する素晴らしい1行の解決策。
corpico

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