web-dev-qa-db-ja.com

接続が閉じたときにリモートで「tail -f」と呼ばれる方法で終了する方法は?

ssh user@remote_Host tail -f /some/fileを実行すると、ssh接続が閉じている場合でもtail -f /some/fileがremote_Hostで実行され続けることに気づきました!

したがって、いくつかの接続と切断の後で、実行中のtail -f /some/fileの数が増えます。 ssh接続が閉じられたときに実際にtail -fを終了する方法は?

24
Dmitry Frank

ssh Host tail -f file

sshクライアントは、TCP接続を介してsshdHostサーバーに接続します。sshdtail -fを実行します。そのstdoutはパイプにリダイレクトされます。sshdは、パイプのもう一方の端からのデータを読み取りますこれをsshdプロトコルにカプセル化してsshクライアントに送信します(rshdを使用すると、tail stdoutが直接ソケットになりますが、sshdは暗号化を追加し、複数のストリームを多重化できます(ポート/エージェント/ X11 /トンネルリダイレクトなど)。 stderr)単一のTCP接続なのでパイプに頼らなければなりません)。

CTRL-Cを押すと、SIGINTがsshクライアントに送信されます。これにより、sshが終了します。 TCP=接続が終了すると、接続が閉じられます。したがって、Hostでもsshdは終了します。tailは強制終了されませんが、そのstdoutはパイプであり、もう一方の端にリーダーがありません。したがって、次にstdoutに何かを書き込むと、SIGPIPEを受信して​​終了します。

に:

ssh -t Host 'tail -f file'

パイプを使用する代わりに、sshdtailの間の通信が疑似ターミナルを介して行われることを除いて、同じことです。 tailのstdoutは、スレーブの疑似端末(/dev/pts/12など)であり、tailによるreadのマスター側のsshd書き込み(tty回線の規律によって変更される可能性がある)はすべて、sshクライアントにカプセル化されて送信されます。

クライアント側で-tを使用すると、sshは端末をrawモードにします。特に、端末の標準モードと端末の信号処理を無効にします。

だから、あなたが押すと Ctrl+C、クライアントの端末回線規則がSIGINTをsshジョブに送信する代わりに、^C文字を接続経由でsshdに送信し、sshdがその^Cをリモート端末のマスター側に書き込みます。そして、リモート端末の回線規律はSIGINTtailに送信します。次に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/-ttを使用するもう1つの欠点は、クライアントでstdoutとstderrが区別されないことです。リモートコマンドのstdoutとstderrの両方がsshクライアントのstdoutに書き込まれます。

$ ssh localhost ls /x  | wc -l
ls: cannot access /x: No such file or directory
0
$ ssh -t localhost ls /x | wc -l
1
33

リモート側での端末割り当てが必要です。

ssh -t user@remote_Host tail -f /some/file

あるいは

ssh -tt user@remote_Host tail -f /some/file
11
Hauke Laging