OpenSSH (実行している可能性が最も高い) は、ログイン シェルを作成するかどうかを決定し、特定のコマンドを実行していない場合にのみ作成します。 man ssh
から :
If command is specified, it is executed on the remote host instead of a login shell.
したがって、ssh サーバーがログイン シェルを作成するかどうかは実装の選択であり、実行するコマンドを指定しても作成されません。
ssh
の間 コマンドを実行して終了する場合は、ログイン環境を取得するよりも、そのコマンドを実行するためだけにシェルを作成することに似ています。それを考えると、OpenSSH を書いている人々は、OpenSSH をそのようなタスクのように扱うことに決めたようです.
コマンドを実行するために、非対話的で非ログインのシェルを作成します。これは、別のコンテキスト/シェルでコマンドを実行する精神であるためです。ただし、通常、非対話型シェルは ~/.bashrc
を自動的にソース化しません。 これは明らかにここで起こっています。 bash
実際にここで私たちを助けようとしています。ドキュメントから
リモート シェル デーモンによって呼び出される
Bash は、リモート シェル デーモン (通常は rshd) またはセキュア シェル デーモン sshd によって実行されるときのように、ネットワーク接続に接続された標準入力で実行されているときを判別しようとします。 Bash は、この方法で実行されていると判断した場合、~/.bashrc ファイルが存在し、読み取り可能であれば、そこからコマンドを読み取り、実行します。 sh として呼び出された場合、これは行われません。 --norc オプションを使用してこの動作を禁止したり、 --rcfile オプションを使用して別のファイルを強制的に読み取ったりすることができますが、通常、rshd も sshd も、これらのオプションを使用してシェルを起動したり、指定することを許可したりしません。 /P>
理由 この振る舞いは、シェルよりも低いレベルにあります:ssh host
(「ログイン シェル」の場合) 疑似端末を使用します sshd
間で通信するために、リモート ホスト上で サーバープロセスとシェル。 ssh host command
sshd
の間のパイプを使用します そして command
、 代わりは。疑似端末は、シェルなどのコマンド インタープリター、またはスクリプト言語の "read-eval-print" モードを対話的に使用するために必要です。タイプミスをバックスペースできるなど、人間に優しい機能を多数実装しています。ただし、オーバーヘッドが大きく、(構成によっては) 任意のデータを変更せずに通過させることができないため、SSH は対話が行われない場合にそれらを使用することを避けます。
時々、SSH のコマンド/コマンドなしヒューリスティックがこれを間違えます。 -t
でオーバーライドできます および -T
スイッチ。たとえば、リモート マシンにログインし、すぐに中断された screen
を再接続するには セッションでは、ssh -t host screen -R
を実行する必要があります; ssh host screen -R
screen
が発生します 端末に接続されていないことについて不平を言う。あなたが実際に望んでいる状況が思い浮かびません -T
を使用するには 、しかし、見つけた場合はそこにあります。