マシンにsshして実行しても問題なく動作するコマンドがありますが、次のようなリモートsshコマンドを使用して実行しようとすると失敗します。
ssh user@IP <command>
異なる環境で両方の方法を使用して「env」の出力を比較します。手動でマシンにログインしてenvを実行すると、実行時よりもはるかに多くの環境変数が得られます。
ssh user@IP "env"
なぜか?
bash
スクリプト言語ではないですか?
マシンにsshして実行しても問題なく動作するコマンドがありますが、次のようなリモートsshコマンドを使用して実行しようとすると失敗します。
ssh user@IP <command>
異なる環境で両方の方法を使用して「env」の出力を比較します。手動でマシンにログインしてenvを実行すると、実行時よりもはるかに多くの環境変数が得られます。
ssh user@IP "env"
なぜか?
bash
スクリプト言語ではないですか?
回答:
シェルにはさまざまなタイプがあります。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変数の値は検索に使用されません ファイル名。
ssh user@host "bash --login -c 'command arg1 ...'"
です。リモートシェルがログイン環境をセットアップするように強調表示する価値があると思います。あなたが引用したセクションは言及して--login
いますが、これを見逃しやすいでしょう。
ssh <ssh options> <IP> bash --login my_script.sh
はリモートマシンでスクリプトを実行し、JAVA_HOME
コマンドを実行する前にプロファイルを取得するのはどうですか?
ssh user@host "source /etc/profile; /path/script.sh"
あなたはそれを変更するには、それとの最良を見つけるかもしれない~/.bash_profile
、~/.bashrc
または何でも。
リモートsshコマンドを実行すると、シェル環境がロードされません。ssh環境ファイルを編集できます。
vi ~/.ssh/environment
その形式は次のとおりです。
VAR1=VALUE1
VAR2=VALUE2
また、オプションのsshd
構成を確認してくださいPermitUserEnvironment=yes
。
私にも同様の問題がありましたが、最終的に〜/ .bashrcが必要なすべてであることがわかりました。
しかし、Ubuntuでは、〜/ .bashrcの処理を停止する行をコメント化する必要がありました。
#If not running interactively, don't do anything
[ -z "$PS1" ] && return
/etc/bash.bashrc
です。
この問題の簡単な解決策は、ターゲットシステムで実行しようとしたscript.shファイルの先頭にソース/ etc / profileを追加することでした。ここのシステムでは、これにより、script.shに必要な環境変数が、ログインシェルから実行されているかのように設定されました。
以前の応答の1つでは、〜/ .bashr_profileなどを使用することが推奨されていました。私はこれに多くの時間を費やしませんでしたが、これの問題は、ログインしたソースシステムのシェルとは異なるターゲットシステムのユーザーにsshすると、ソースシステムユーザーが原因であるように見えました〜に使用する名前。
〜/ .bashrcの非対話型シェルのチェックの上に必要な環境変数をエクスポートするだけです。