マシンに ssh して実行すると正常に実行されるコマンドがありますが、次のようなリモート ssh コマンドを使用して実行しようとすると失敗します。
ssh user@IP <command>
両方の方法を使用して「env」の出力を比較すると、異なる環境で結果が得られます。マシンに手動でログインして env を実行すると、実行時よりもはるかに多くの環境変数が取得されます。
ssh user@IP "env"
理由はありますか?
マシンに ssh して実行すると正常に実行されるコマンドがありますが、次のようなリモート ssh コマンドを使用して実行しようとすると失敗します。
ssh user@IP <command>
両方の方法を使用して「env」の出力を比較すると、異なる環境で結果が得られます。マシンに手動でログインして env を実行すると、実行時よりもはるかに多くの環境変数が取得されます。
ssh user@IP "env"
理由はありますか?
シェルにはさまざまな種類があります。SSH コマンド実行シェルは非対話型シェルですが、通常のシェルはログイン シェルまたは対話型シェルです。man bash からの説明は次のとおりです。
ログインシェルは、引数の最初の文字を持つシェルです ゼロは - または --login オプションで始まるものです。 対話型シェルは、オプションなしで開始されるシェルです 引数と -c オプションなしの標準入力 とエラーは両方とも端子に接続されています (決定されたとおり) isatty(3)) によって、または -i オプションで開始されたもの。PS1は set および $- には、bash がインタラクティブな場合は i が含まれ、 シェル スクリプトまたはスタートアップ ファイルを使用して、この状態をテストします。 次の段落では、bash がどのように実行するかについて説明します。 起動ファイル。いずれかのファイルが存在するが存在しない場合 読み取り、bash はエラーを報告します。チルダはファイルに展開されます 以下のチルダ展開で説明されている名前 拡張セクション。 bash が対話型ログイン シェルとして、または --login オプションを指定した非対話型シェル。 ファイル /etc/profile からコマンドを読み取り、実行します。 そのファイルが存在します。そのファイルを読み取った後、 ~/.bash_profile、~/.bash_login、~/.profile、その中に 最初のコマンドから順に読み取り、実行します。 存在し、読み取り可能です。--noprofile オプションは シェルの起動時にこの動作を禁止するために使用されます いいえ。 ログイン シェルが終了すると、bash はコマンドを読み取って実行します ファイル ~/.bash_logout (存在する場合) から。 ログインシェルではないインタラクティブシェルが 起動すると、bash は ~/.bashrc からコマンドを読み取り、実行します。 そのファイルが存在する場合。これは、 --norc オプション。--rcfile ファイル オプションは bash を強制します 代わりにファイルからコマンドを読み取って実行する ~/.bashrc. bash が非対話的に開始された場合、シェルを実行するには たとえば、スクリプトで変数 BASH_ENV を検索します。 そこに現れればその価値を広げ、 展開された値をファイルの名前として使用して読み取る そして実行します。Bash は次のコマンドのように動作します。 実行されました: if [ -n "$BASH_ENV" ]; それから 。"$BASH_ENV"; フィ ただし、PATH 変数の値は検索に使用されません ファイル名に。
コマンドを実行する前にプロファイルを取得するのはどうですか?
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
~/.bashrc の非対話型シェルのチェックの上に必要な環境変数をエクスポートするだけです。
この問題の簡単な解決策は、ターゲット システムで実行しようとしていた script.sh ファイルの先頭にソース /etc/profile を追加することであることがわかりました。このシステムでは、これにより、script.sh が必要とする環境変数が、ログイン シェルから実行されているかのように構成されていました。
以前の回答の 1 つで、 ~/.bashr_profile などを使用することが提案されました。私はこれに多くの時間を費やしませんでしたが、これに関する問題は、ログイン元のソース システムのシェルとは異なるターゲット システムのユーザーに ssh すると、ソース システムのユーザーが~ に使用される名前。