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


12

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一時的に別の場所に格納した場合、これらの行はどちらもエコーされません。)

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

$ 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はまだリモートマシンにログインしてコマンドを実行していませんか?


.bashrc?の出力 そのファイルは出力を生成するものではありません。からの出力により、.bashrcsshをトランスポートとして使用しているすべてのツールが壊れる可能性があります。
kasperd 2017

けっこうだ。この場合、の数行は.bashrcエラーをスローしていましたが、同様の行はエラーをスローして.bash_profileいませんでした。問題のある行を修正する前に、この不一致を調査する機会を得ました。
Ryan Lue 2017

回答:


12

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も通常、これらのオプションでシェルを呼び出したり、それらを指定したりすることはできません。


「...ログインシェルの代わりにリモートホストで実行されます。」この二分法はありません。コマンドが実行されているリモートホスト上ではなく、ログインシェルで、またはされたコマンドは、リモートホスト上で実行され、代わりのログインシェルが実行されていますか?前者の場合、どちらか/またはそれはどうですか?(それは通常ではありません両方?)後者の場合、それはまだのコンテキストで実行されますいくつかのシェル、それはないですか?(インタラクティブな非ログインのものですか?)では、私の質問もセマンティクスについてです。「ログインシェル」は何を意味し、OpenSSHは単一のコマンド用に作成しないように設計されているのですか?
Ryan Lue 2017

@RyanLueシェルのさまざまな「フレーバー」により、特定のタスクがより簡単/より安全/最適化されます。などを行うにsshはログインが必要ですが、実装者は、たとえば、コマンドを実行して戻るように要求するなど、特定の状況下でログインシェルが実行する追加の手順を必要としないため、その手順をスキップします。実際に実行されるシェルがあるので、私は主に環境をセットアップすることを想定しています。シェルはログインしたユーザーに提供されないため、ユーザーは新しいシェルを起動してそれを実行したかのように扱いますコマンド
Eric Renouf 2017

「だから、実際に実行するのシェルがあり、私は環境のセットアップにほとんど推測...」<しかし、私はちょうどこのを試し、それが表示されssh <host> <command>、既存のログインシェルの環境継承しません。たとえば、ソース$ ssh <host> \$PATHを使用しない.bash_profile場合.profileと同じように(またはそのまま)パスを返します...実際的な意味で、なぜそのステップを回避したいのですか?
Ryan Lue 2017

「...実装者は、コマンドを実行して戻るように要求するなど、特定の状況下では、ログインシェルが行う追加の手順を必要としない/メリットがないため、スキップすることを明らかにしました。」<また、このデザインの選択に関する明確化/洞察を具体的に探しています。私は自分PATHで定義します.profile—リモートホストで任意のコマンドを実行する前にロードしたい種類ではないでしょうか。
Ryan Lue 2017

1
@RyanLue Boks sshサーバーは、sshの明確な使用法を区別し、それぞれに権限を付与できます。リモートログイン、リモート実行、リモートコピー、おそらくこれは、あなたが説明した動作をする理由を理解するのに役立ちます。高度なセキュリティ環境では、リモートログイン(インタラクティブな使用)は要求しきれない場合があります。opensshは、.bash_profileまたはchrootでrbash / rkshおよび 'logout'を使用することによって制限できます。
bbaassssiiee 2017

4

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

SSHのコマンド/コマンドなしのヒューリスティックがこれを誤ることがあります。-tand -Tスイッチで上書きできます。たとえば、リモートマシンにログインし、中断されたscreenセッションをすぐに再接続するには、次の操作を行う必要がありssh -t host screen -Rます。端末に接続されていないと文句を言うssh host screen -Rでしょうscreen。実際にを使用したいと思うような状況は考えられませんが、-T見つけた場合はそこにあります。


1

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

/unix/170493/login-non-login-and-interactive-non-interactive-shells

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

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

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


わかりましたが、これは興味深い質問を提起.bashrcします。非インタラクティブなコンテキストで呼び出された場合(つまり、「プロンプトステートメント」/ $PS1変数がない場合)ソースから取得されないように記述される場合があります。しかしssh <host> <command> 、明らかに非インタラクティブです。つまり、コマンドプロンプトは表示されませ。では、なぜOpenSSHは.bashrc、この一見ログインしているように見える、非インタラクティブなユースケースに対して、非ログインでインタラクティブなプロンプト(をソースしようとするプロンプト)を作成するように設計されているのでしょうか?
Ryan Lue 2017
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.