マシンに 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 すると、ソース システムのユーザーが~ に使用される名前。