web-dev-qa-db-ja.com

`ssh <Host>`はログインシェルですが、 `ssh <Host> <command>`はログインシェルではありませんか?

ssh <Host> <command>構文を使用してSSHホストで直接コマンドを実行すると、.bashrc(または.bash_profile)の出力ではなく、.profileの出力が表示されることに気づきました。

たとえば、次のコマンドを両方のファイルの先頭に配置すると、

echo ${BASH_SOURCE[0]}

手動で.bash_profileをソースします(これは.bashrcを順にソースします)。

$ . .bash_profile
.bash_profile
.bashrc

これは、コマンドのssh <Host>形式を使用して、SSH経由でこのコンピューターにリモートでログインした場合に表示される出力と同じです。 (そして、.bash_profileを一時的にどこかに格納した場合、これらの行はどちらもエコーされません。)

ただし、sshssh <Host> <command>形式を使用してリモートマシンで直接コマンドを実行すると、出力は次のようになります。

$ ssh <Host> echo foo
/home/rlue/.bashrc
foo

.bash_profile.bashrcの違いは、前者はログインシェル用であり、後者はインタラクティブな非ログインシェル用であることを理解しています。

私は次のように結論しました:

  1. ssh <Host>.bash_profileのみをソースしますが、
  2. ssh <Host> <command>.bashrcのみをソースします。つまり、
  3. 前者はログインシェルであり、後者はそうではありません。

これらの結論は正しいですか? ssh <Host> <command>が対話型の非ログインシェルとして扱われるのはなぜですか? SSHはまだコマンドを実行するためにリモートマシンにログインしていませんか?

12
Ryan Lue

OpenSSH(おそらくあなたが実行しているもの)は、ログインシェルを作成するかどうかを決定し、特定のコマンドを実行していない場合にのみ作成します。 man sshから:

 If command is specified, it is executed on the remote Host instead of a
 login Shell.

そのため、ログインシェルを作成するかどうかに関係なく、sshサーバーの実装の選択であり、実行するコマンドを指定した場合は実行されません。

sshはログインを実行しますが、コマンドを実行して終了する場合は、ログイン環境を取得するよりも、そのコマンドを実行するためにシェルを作成することに非常によく似ています。それを考えると、OpenSSHを書いている人々はそれをそのような仕事のように扱うことに決めたようです。

コマンドを実行するための非インタラクティブ、非ログインシェルを作成します。これは、別のコンテキスト/シェルでコマンドを実行する精神だからです。ただし、通常、非インタラクティブシェルは~/.bashrcを自動的にソースしません。これは明らかにここで発生しています。 bashは実際にここで私たちを助けようとしています。から ドキュメント

リモートシェルデーモンによって呼び出されます

Bashは、標準の入力がネットワーク接続に接続された状態で実行されているとき、リモートシェルデーモン(通常はrshd)またはセキュアシェルデーモンsshdによって実行されている場合を判断します。この方法で実行されているとBashが判断した場合、そのファイルが存在して読み取り可能であれば、〜/ .bashrcからコマンドを読み取って実行します。 shとして呼び出された場合、これは行われません。 --norcオプションを使用してこの動作を禁止し、-rcfileオプションを使用して別のファイルを強制的に読み取ることができますが、rshdもsshdも通常、これらのオプションを使用してシェルを呼び出したり、それらを指定したりできません。

12
Eric Renouf

この動作のwhyはシェルよりも低いレベルにあります:ssh Host(「ログインシェル」の場合)は pseudoterminal リモートホスト上で、sshdサーバープロセスとシェルの間で通信します。 ssh Host commandは、代わりにsshdcommandの間のパイプを使用します。シェルなどのコマンドインタープリターやスクリプト言語の " read-eval-print "モードを対話的に使用するには、疑似ターミナルが必要です。それらは、タイプミスを介してバックスペースすることができるように人間に優しい機能の束を実装します。ただし、オーバーヘッドが大きくなり、(構成によっては)任意のデータを変更せずに通過させることができないため、SSHは相互作用が発生しない場合にそれらの使用を回避します。

SSHのコマンド/コマンドなしのヒューリスティックがこれを誤ることがあります。 -tおよび-Tスイッチでオーバーライドできます。たとえば、リモートマシンにログインし、中断されたscreenセッションをすぐに再接続するには、ssh -t Host screen -Rを実行する必要があります。 ssh Host screen -Rは、screenが端末に接続されていないことを報告します。実際にwantを使用して-Tを使用するような状況は考えられませんが、見つけた場合はあります。

4
zwol

まず、さまざまなタイプを確認する必要があります。これを読むことができます。

https://unix.stackexchange.com/questions/170493/login-non-login-and-interactive-non-interactive-shells

これでb​​ashrcを開くと、最初にこれが表示されます。

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

つまり、システムへのアクセス方法に応じて、このファイルはコードを内部にロードするかどうかを決定します。

1
Genaro Morales