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