web-dev-qa-db-ja.com

$ PATHが正しく指定されていても、Bashがコマンドを見つけられないのはなぜですか?

ファイルにコマンドへのパスを指定しています/ etc/profile

export PATH=$PATH:/usr/app/cpn/bin

私のコマンドは次の場所にあります:

$ which ydisplay 
/usr/app/cpn/bin/ydisplay

したがって、「echo $ PATH」出力を実行すると、次のようになります。

$ echo $PATH
...:/usr/app/cpn/bin

そして、すべてが大丈夫ですが、SSH経由でコマンドを起動しようとすると、エラーが発生します。

$ ssh 127.0.0.1 ydisplay
$ bash: ydisplay: command not found

しかし、私の道はまだ存在しています:

$ ssh 127.0.0.1 echo $PATH
...:/usr/app/cpn/bin

SSHセッション中にBashがydisplayを見つけられない理由と、この問題を回避するためにSSHを適切に構成する方法を教えてください。

さらに、現在のユーザーのローカルファイル.bashrcで$ PATHを指定すると、すべて正しく動作します。しかし、ユーザーごとに多数のファイルを指定するのではなく、1つのファイルのみを変更したいと思います。これが私が求めている理由です。

9
SIGSEGV

tl; dr

ssh 127.0.0.1 ydisplayではなく~/.bashrcソース/etc/profileを実行します。代わりに~/.bashrcでパスを変更してください。

詳細

/etc/profileが読み取られるのは、シェルが「ログインシェル」の場合のみです。

Bashリファレンスマニュアル から:

Bashがログインシェルとして呼び出されると、...ファイル/ etc/profileからコマンドを最初に読み取り、実行します。

ただし、ssh 127.0.0.1 ydisplayを実行すると、bashはログインシェルとして起動されません。それでも、別の起動ファイルを読み取ります。 Bashリファレンスマニュアル は次のように述べています。

...が... sshdによって実行されたとき。 ... ~/.bashrcからコマンドを読み取って実行します

したがって、PATH設定を~/.bashrcに配置する必要があります。

ほとんどのシステムでは、~/.bash_profile~/.bashrcをソースとするため、設定を両方のファイルに配置するのではなく、~/.bashrcにのみ配置できます。

すべてのユーザーの設定を変更する標準的な方法はありませんが、ほとんどのシステムには/etc/bashrc/etc/bash.bashrcなどがあります。

それができない場合は、pam_envをセットアップし、PATH設定を/etc/environmentに入れます。

以下も参照してください。

5
Mikel

歴史的に、プロファイルファイル(/etc/profileおよび~/.profile)は、ログイン時に呼び出され(テキストコンソールで他に何ですか?)、多くの目的を果たしました。

  • セッションの環境変数とその他のパラメーター(umaskなど)を設定します。
  • セッションの開始時に追加のプログラムを実行します(電子メール通知など)。
  • シェルとは異なる場合(たとえば、別のシェルまたはXウィンドウ)、セッションのプログラムを実行します。
  • 端末パラメータを設定します(例:stty)。
  • シェルパラメータ(エイリアスなど)を設定します。

これらの目的はすべて、後でないと個別に識別されませんでした。プロファイルスクリプトは、インタラクティブセッション(端末の相互作用、他のプログラムの起動)でのみ意味のあることを行う可能性があるため、リモートシェル呼び出し( rsh )が導入されたとき、rshの作成者は、ログインシェルとしてのリモートシェル。プロファイルスクリプトは実行されません。 (rshdの一部のバージョンには、リモートシェルをログインシェルとして実行するオプションがあります。)sshは、rshのドロップイン置換としてこの動作をコピーしました。

プロファイルスクリプトを実行する場合は、スクリプトを明示的に呼び出すことができます。

ssh 127.0.0.1 '. /etc/profile; . ~/.profile; ydisplay'

シェル内にプロファイルスクリプトをロードするコマンド.に注意してください。これらは、外部プログラムではなく、シェル内で実行されるコマンドです。

すべてのユーザーに対してグローバルに環境変数を設定する場合は、多くのシステムで別の方法があります。/etc/profileで定義する代わりに、/etc/environmentで定義します。このファイルは pam_env モジュールを通じて読み込まれます。ほとんどのLinuxディストリビューションはそれを読むように設定されています。

ログインシェルがbashの場合は、さらに可能性があります。通常、 .bashrc)に環境変数を設定することはできません (インタラクティブシェルを使用して端末を経由する場合を除いて、Xセッションでは設定されないため、テキストコンソールまたはsshを介してインタラクティブにログインする場合に設定します。別のプログラム内でシェルを呼び出すと、カスタム設定が上書きされるためです)。ただし、bashには私が理解したことのない奇妙な機能があります。2つの無関係な状況で~/.bashrcを読み取ります。

  • ログインシェルではないインタラクティブシェル。
  • ログインシェルではない非インタラクティブシェルで、bashがrshdまたはsshdによって呼び出されたと判断した場合。

Sshでコマンドを実行すると、2番目のケースになります。 /etc/profileから.profileおよび.bashrcを読み取ることで、プロフィールを読み取るように設定できます。 ~/.bashrcに次のコードを含めます:

case $- in
  *i*) :;; # this is an interactive Shell, fine
  *) # This is not an interactive Shell! This must be a non-interactive remote Shell session.
    . /etc/profile; . ~/.profile
    return;;
esac