ssh [email protected] _host tail -f / some / fileを実行すると気づきました 、次に tail -f / some / file ssh接続が閉じられてもremote_hostで実行され続けます!
したがって、いくつかの接続と切断の後、実行中の tail -f / some / fileの数 成長します。 tail -fを実際に終了する方法 ssh接続が閉じられたとき?
承認された回答:
で
ssh host tail -f file
ssh クライアントはsshdに接続します host上のサーバー TCP接続を介して。 sshd tail -fを実行します stdoutがパイプにリダイレクトされます。 sshd パイプのもう一方の端から来るものを読み取り、それをsshdプロトコルにカプセル化して、 sshに送信します。 クライアント。 ( rshdを使用 、 tail stdoutは直接ソケットでしたが、 sshd 暗号化を追加し、単一のTCP接続で複数のストリーム(ポート/エージェント/ X11 /トンネルリダイレクト、stderrなど)を多重化できるため、パイプに頼る必要があります。
Ctrl-Cを押すと、SIGINTが sshに送信されます。 クライアント。これにより、 sshが発生します 死ぬ。死ぬと、TCP接続は閉じられます。したがって、 host 、 sshd 同様に死ぬ。 テールコード> は殺されませんが、そのstdoutは、もう一方の端にリーダーがないパイプになります。したがって、次にstdoutに何かを書き込むと、SIGPIPEを受け取り、死にます。
で:
ssh -t host 'tail -f file'
パイプを使用する代わりに、 sshd 間の通信を行うことを除いて、同じことです。 およびtail 擬似端末を介してです。 テールコード> のstdoutは、スレーブ疑似端末です( / dev / pts / 12 など)。 )およびその他の tail readがあります sshd によるマスター側(おそらくttyラインの規律によって変更された) カプセル化されてsshに送信されます クライアント。
クライアント側では、 -tを使用します 、 ssh 端末をrawに配置します モード。特に、これにより、端末の正規モードと端末の信号処理が無効になります。
したがって、 Ctrl + Cを押すと 、クライアントの端末回線の規律の代わりに、SIGINTを sshに送信します ^ Cを送信するだけのジョブ sshdへの接続を介した文字 およびsshd その^Cを書き込みます リモート端末のマスター側に。そして、リモート端末の回線規律は SIGINTを送信します tail 。 テールコード> その後、死に、 sshd 接続を終了して閉じ、 ssh 終了します(ポート転送などでまだビジーでない場合)。
また、 -tを使用します 、 sshの場合 クライアントが停止します(たとえば、〜。を入力した場合 )、接続が閉じられ、 sshd 死ぬ。その結果、SIGHUPは tailに送信されます 。
ここで、 -tを使用することに注意してください 副作用があります。たとえば、デフォルトの端末設定では、 \ n 文字は\r \ nに変換されます また、リモートシステムによってはさらに多くのことが発生する可能性があるため、 stty -opostを発行することをお勧めします。 (出力の後処理を無効にするため)リモートホストで、その出力が端末を対象としていない場合:
$ ssh localhost 'echo x' | hd
00000000 78 0a |x.|
00000002
$ ssh -t localhost 'echo x' | hd
00000000 78 0d 0a |x..|
00000003
$ ssh -t localhost 'stty -opost; echo x' | hd
00000000 78 0a |x.|
00000002
-tを使用するもう1つの欠点 / -tt stdoutとstderrはクライアントで区別されないということです。リモートコマンドのstdoutとstderrの両方がsshに書き込まれます クライアントの標準:
$ ssh localhost ls /x | wc -l
ls: cannot access /x: No such file or directory
0
$ ssh -t localhost ls /x | wc -l
1