ssh user@remote_Host tail -f /some/file
を実行すると、ssh接続が閉じている場合でもtail -f /some/file
がremote_Hostで実行され続けることに気づきました!
したがって、いくつかの接続と切断の後で、実行中のtail -f /some/file
の数が増えます。 ssh接続が閉じられたときに実際にtail -f
を終了する方法は?
に
ssh Host tail -f file
ssh
クライアントは、TCP接続を介してsshd
でHost
サーバーに接続します。sshd
はtail -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'
パイプを使用する代わりに、sshd
とtail
の間の通信が疑似ターミナルを介して行われることを除いて、同じことです。 tail
のstdoutは、スレーブの疑似端末(/dev/pts/12
など)であり、tail
によるread
のマスター側のsshd
書き込み(tty回線の規律によって変更される可能性がある)はすべて、ssh
クライアントにカプセル化されて送信されます。
クライアント側で-t
を使用すると、ssh
は端末をraw
モードにします。特に、端末の標準モードと端末の信号処理を無効にします。
だから、あなたが押すと Ctrl+C、クライアントの端末回線規則がSIGINTをssh
ジョブに送信する代わりに、^C
文字を接続経由でsshd
に送信し、sshd
がその^C
をリモート端末のマスター側に書き込みます。そして、リモート端末の回線規律はSIGINT
をtail
に送信します。次に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
リモート側での端末割り当てが必要です。
ssh -t user@remote_Host tail -f /some/file
あるいは
ssh -tt user@remote_Host tail -f /some/file