sshコマンドはセッションを終了します

sshコマンドはセッションを終了します

私はこれを持っています:

ssh -i "alex-kp.pem" '[email protected]' '

  cd codes/vbe
  eval $(ssh-agent)
  ssh-add -D
  ssh-add ~/.ssh/id_vbe
'

コマンドを実行してセッションを終了するので、ローカルコンピュータに戻ります。理由を知っている人はいますか?

答え1

リモートシステムで実行するコマンド(つまり一連のコマンド)を提供しました。コマンド(これらのコマンド)が完了すると、セッションは終了します。これは定義されており、予想される動作でなければなりませんman ssh。以下を参照してください。

コマンドを指定すると、ログインシェルではなくリモートホストで実行されます。

hostnameリモートシステムで実行されるより簡単な例

ssh -i alex-kp.pem [email protected] hostname

答え2

遠隔側では何が起こるのか

Localはssh user@server 'shell_code'SSHサーバーを次のように実行します。

"$SHELL" -c 'shell_code'

私はそう言うわけではない正確にこれと同じですが、何が起こっているのかを理解するのに十分なほど近いです。まるでシェルから呼び出すかのように書いたので、おなじみのようですが、実際にはまだシェルはありません。

この方法で呼び出されたシェルに達しましたshell_code。あなたの場合、コードは複数行で、何も変更されません。

plainなどのシェルコードがない場合、ssh user@serverSSHサーバーは別のものを起動します。

"$SHELL" -i

もう一度申し上げますが、そうではないと申し上げたいです。正確にこのように。

この方法で呼び出されたシェルは次のとおりです。インタラクティブシェルはプロンプトを印刷し、入力を待ちます。これがあなたが達成したい行動のようです。

SSHサーバーは、ローカル通話形式に応じて意図的に1つの形式を使用しますssh。後者の形式は対話型の使用に非常に適しており、電子形式は、一部の非対話型シェルコードをローカルのようにリモートで実行することもできます。たとえば、ローカルで次のことができます。

<data md5sum

ただし、ローカルで欠落している場合はmd5sumリモートを使用できます。

<data ssh user@server md5sum

md5sumタスクの完了後、ローカルシャットダウンと同様に、リモートもタスクのssh … md5sum完了md5sum後に終了します。とても便利です。

または、リモートファイルにパイプすることもできます。

<data ssh user@server 'cat >copy'

また、catリモートシェルとローカルシェルは、ssh適切な場合は自動的にシャットダウンされます。

または、サーバーに時間を要求することもできます。

ssh user@server date

これはlocalのように動作し、date対話型リモートシェルには入りません。


対話型シェルが自動的に終了する場合

私は[ ssh … date]がデフォルトで終了しないと予想しました。端末にコマンドを入力するとデフォルトで終了しますか?

もちろん。コマンドの読み込み中にEOFに達すると、対話型シェルは終了します。問題は、Ctrl+()を押すdまで端末でEOFを「経験」しないことです。1回または2回)。これが端末で動作する方法です。ただし、インタラクティブシェルが通常のファイルまたはパイプから読み取られるようにすると、予想される瞬間に正確にEOFが表示されます。

{ echo date; echo sleep 5; echo date; } | bash -i

これで終了します。

したがって、実際にやることがない場合、すべてのシェルはデフォルトで終了します。端末からデータを読み取ると、対話型シェルは「終了しません」と呼ばれます。意図的に入力がいつでも現れる可能性があると仮定して、現在の入力がないときにEOFをトリガしないように設計されています。これは、シェルや一般的なプログラムではなく、端末に関連しています。つまり、シャットダウンのようなものですが、</etc/fstab catttyからの一般的な読み取りは無期限に機能します。同じ話です。cat


リモートttyの重要性

SSHサーバーがシェルを実行する2つの方法は、単純な形式以上の違いがあります。リモートインタラクティブコマンドは、ローカルttyを使用するとうまく機能します(したがって、ローカルsshとコマンドの間のサーバー側ttyです)。ただし、md5sumリモート非対話型コマンド(例)は、ttyが割り当てられていない場合でもうまく機能します。 SSHサーバーはttyを割り当てたり割り当てたりせず、自動的に割り当てられます(ただし、必要に応じてsshオプションで明示的に選択できます)。私は2つを最大限に活用しようとし、質問(そして答え)から洞察を得ることができると思います。-t-tt-TSSH には独立した stdin、stdout、stderr、tty があります。


あなたは何ができますか?

最初のプロンプトを表示する前に、一部のシェルコードを実行するリモートインタラクティブシェルが必要なようです。最も簡単な方法は、コードを正しい起動スクリプト(~/.bashrcシェルがBashの場合)に配置しssh(シェルコードを渡さずに)対話型リモートシェルに配置することです。これは永続的なソリューションであるため、リクエスト時にワンタイムコードを実行してメッセージを引き続き受信したい場合は便利ではありません。

要求時にシェルコードを実行するには、次のものが必要です。

ssh -t … '
  exec bash --rcfile <(cat <<"EOF"
    # your custom shell code here
    . ~/.bashrc
    # and/or here
EOF
) -i'

これは、SSHサーバーによって開始されたシェルがこれを理解し<(…)(Bashがこれを理解する)、最終的な対話型シェルとして必要なシェルがBashであると仮定します。

SSHサーバーはまだttyを使用する非対話型シェルを実行します-t。シェルはexec代わりにカスタムファイルをインポートするための対話型Bashを使用します~/.bashrc。ファイルはプロセス交換のパイプになり、その内容はカスタムシェルコードとソースガイドラインになります~/.bashrc。これにより、最終シェルはカスタムシェルコードを実行し、プロンプトを表示します。

SSHサーバーによって直接作成された対話型シェルはログインシェルであり、/etc/profileここでは両方のシェルがログインシェルではありません。を使用して最終シェルを実行できますが、-lそれを無視します--rcfile

しかし、あなたの特定カスタムシェルコードは生き残るように設定しますexec(しばしば継承できます)。これは、コードスニペットを次のように単純化できることを意味します。

ssh -t … '
  cd codes/vbe
  eval $(ssh-agent)
  ssh-add -D
  ssh-add ~/.ssh/id_vbe
  exec bash -i
'

この場合-l、必要に応じて最終的なBashをログインシェルとして追加して作成できると思います。ログインシェルと非ログインシェルは異なるファイルを持つことに注意してください。これらのファイルは互いに生成できます(つまり、~/.bash_profile互いに生成できます~/.bashrc)。非対話型Bashもソースを提供できます。~/.bashrc;そして、2つのリモートシェルが順番にあり、それぞれが何かを得ることができます。リモコンは~/.bashrcおそらく2回購入するでしょう。含有量によっては副作用が発生する場合があります。

ssh …まったく別の方法は、ローカルスクリプトから呼び出すことです(シェルコードは不要です)expect。このスクリプトは必要なシェルコードを挿入し、最終的には一致を介してinteractリモートプロンプトを検出できると仮定します@*:*$

expect -c '
 spawn ssh -i alex-kp.pem [email protected]
 expect "@*:*$ "
 send "cd codes/vbe\r"
 expect "@*:*$ "
 send "eval \$(ssh-agent)\r"
 expect "@*:*$ "
 send "ssh-add -D\r"
 expect "@*:*$ "
 send "ssh-add ~/.ssh/id_vbe\r"
 interact
'

AWSはわかりませんが、通常、切断後も生き残ることも、そうでない場合もありますssh-agenteval $(ssh-agent)生き残るには、ssh-agent -kリモートシェルを終了する前に手動でclean()することをお勧めします。

関連情報